@substrate-ai/factory 0.19.54

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 (885) hide show
  1. package/dist/__tests__/config.test.d.ts +11 -0
  2. package/dist/__tests__/config.test.d.ts.map +1 -0
  3. package/dist/__tests__/config.test.js +215 -0
  4. package/dist/__tests__/config.test.js.map +1 -0
  5. package/dist/__tests__/factory-run-command.test.d.ts +12 -0
  6. package/dist/__tests__/factory-run-command.test.d.ts.map +1 -0
  7. package/dist/__tests__/factory-run-command.test.js +454 -0
  8. package/dist/__tests__/factory-run-command.test.js.map +1 -0
  9. package/dist/__tests__/factory-validate-command.test.d.ts +15 -0
  10. package/dist/__tests__/factory-validate-command.test.d.ts.map +1 -0
  11. package/dist/__tests__/factory-validate-command.test.js +339 -0
  12. package/dist/__tests__/factory-validate-command.test.js.map +1 -0
  13. package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.d.ts +72 -0
  14. package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.d.ts.map +1 -0
  15. package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.js +121 -0
  16. package/dist/__tests__/fixtures/advanced-cross-project-validation.dot.js.map +1 -0
  17. package/dist/__tests__/fixtures/llm-edge-routing.dot.d.ts +28 -0
  18. package/dist/__tests__/fixtures/llm-edge-routing.dot.d.ts.map +1 -0
  19. package/dist/__tests__/fixtures/llm-edge-routing.dot.js +55 -0
  20. package/dist/__tests__/fixtures/llm-edge-routing.dot.js.map +1 -0
  21. package/dist/__tests__/fixtures/manager-loop.dot.d.ts +34 -0
  22. package/dist/__tests__/fixtures/manager-loop.dot.d.ts.map +1 -0
  23. package/dist/__tests__/fixtures/manager-loop.dot.js +61 -0
  24. package/dist/__tests__/fixtures/manager-loop.dot.js.map +1 -0
  25. package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.d.ts +42 -0
  26. package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.d.ts.map +1 -0
  27. package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.js +118 -0
  28. package/dist/__tests__/fixtures/parallel-fan-out-fan-in.dot.js.map +1 -0
  29. package/dist/__tests__/fixtures/subgraph-parent.dot.d.ts +35 -0
  30. package/dist/__tests__/fixtures/subgraph-parent.dot.d.ts.map +1 -0
  31. package/dist/__tests__/fixtures/subgraph-parent.dot.js +69 -0
  32. package/dist/__tests__/fixtures/subgraph-parent.dot.js.map +1 -0
  33. package/dist/__tests__/integration/advanced-graph-events.test.d.ts +19 -0
  34. package/dist/__tests__/integration/advanced-graph-events.test.d.ts.map +1 -0
  35. package/dist/__tests__/integration/advanced-graph-events.test.js +288 -0
  36. package/dist/__tests__/integration/advanced-graph-events.test.js.map +1 -0
  37. package/dist/__tests__/integration/checkpoint-resume.test.d.ts +10 -0
  38. package/dist/__tests__/integration/checkpoint-resume.test.d.ts.map +1 -0
  39. package/dist/__tests__/integration/checkpoint-resume.test.js +125 -0
  40. package/dist/__tests__/integration/checkpoint-resume.test.js.map +1 -0
  41. package/dist/__tests__/integration/conditional-pipeline.test.d.ts +10 -0
  42. package/dist/__tests__/integration/conditional-pipeline.test.d.ts.map +1 -0
  43. package/dist/__tests__/integration/conditional-pipeline.test.js +106 -0
  44. package/dist/__tests__/integration/conditional-pipeline.test.js.map +1 -0
  45. package/dist/__tests__/integration/convergence-validation.test.d.ts +14 -0
  46. package/dist/__tests__/integration/convergence-validation.test.d.ts.map +1 -0
  47. package/dist/__tests__/integration/convergence-validation.test.js +449 -0
  48. package/dist/__tests__/integration/convergence-validation.test.js.map +1 -0
  49. package/dist/__tests__/integration/epic44-coverage-gate.test.d.ts +12 -0
  50. package/dist/__tests__/integration/epic44-coverage-gate.test.d.ts.map +1 -0
  51. package/dist/__tests__/integration/epic44-coverage-gate.test.js +58 -0
  52. package/dist/__tests__/integration/epic44-coverage-gate.test.js.map +1 -0
  53. package/dist/__tests__/integration/epic45-coverage-gate.test.d.ts +11 -0
  54. package/dist/__tests__/integration/epic45-coverage-gate.test.d.ts.map +1 -0
  55. package/dist/__tests__/integration/epic45-coverage-gate.test.js +64 -0
  56. package/dist/__tests__/integration/epic45-coverage-gate.test.js.map +1 -0
  57. package/dist/__tests__/integration/epic46-scenario-primary-executor.test.d.ts +2 -0
  58. package/dist/__tests__/integration/epic46-scenario-primary-executor.test.d.ts.map +1 -0
  59. package/dist/__tests__/integration/epic46-scenario-primary-executor.test.js +285 -0
  60. package/dist/__tests__/integration/epic46-scenario-primary-executor.test.js.map +1 -0
  61. package/dist/__tests__/integration/events.test.d.ts +8 -0
  62. package/dist/__tests__/integration/events.test.d.ts.map +1 -0
  63. package/dist/__tests__/integration/events.test.js +194 -0
  64. package/dist/__tests__/integration/events.test.js.map +1 -0
  65. package/dist/__tests__/integration/graphs.d.ts +59 -0
  66. package/dist/__tests__/integration/graphs.d.ts.map +1 -0
  67. package/dist/__tests__/integration/graphs.js +164 -0
  68. package/dist/__tests__/integration/graphs.js.map +1 -0
  69. package/dist/__tests__/integration/helpers.d.ts +127 -0
  70. package/dist/__tests__/integration/helpers.d.ts.map +1 -0
  71. package/dist/__tests__/integration/helpers.js +167 -0
  72. package/dist/__tests__/integration/helpers.js.map +1 -0
  73. package/dist/__tests__/integration/integrity.test.d.ts +8 -0
  74. package/dist/__tests__/integration/integrity.test.d.ts.map +1 -0
  75. package/dist/__tests__/integration/integrity.test.js +198 -0
  76. package/dist/__tests__/integration/integrity.test.js.map +1 -0
  77. package/dist/__tests__/integration/llm-edge-routing.test.d.ts +21 -0
  78. package/dist/__tests__/integration/llm-edge-routing.test.d.ts.map +1 -0
  79. package/dist/__tests__/integration/llm-edge-routing.test.js +341 -0
  80. package/dist/__tests__/integration/llm-edge-routing.test.js.map +1 -0
  81. package/dist/__tests__/integration/manager-loop.test.d.ts +24 -0
  82. package/dist/__tests__/integration/manager-loop.test.d.ts.map +1 -0
  83. package/dist/__tests__/integration/manager-loop.test.js +276 -0
  84. package/dist/__tests__/integration/manager-loop.test.js.map +1 -0
  85. package/dist/__tests__/integration/multi-type-graph.test.d.ts +10 -0
  86. package/dist/__tests__/integration/multi-type-graph.test.d.ts.map +1 -0
  87. package/dist/__tests__/integration/multi-type-graph.test.js +100 -0
  88. package/dist/__tests__/integration/multi-type-graph.test.js.map +1 -0
  89. package/dist/__tests__/integration/parallel-fan-out-fan-in.test.d.ts +22 -0
  90. package/dist/__tests__/integration/parallel-fan-out-fan-in.test.d.ts.map +1 -0
  91. package/dist/__tests__/integration/parallel-fan-out-fan-in.test.js +515 -0
  92. package/dist/__tests__/integration/parallel-fan-out-fan-in.test.js.map +1 -0
  93. package/dist/__tests__/integration/persistence.test.d.ts +8 -0
  94. package/dist/__tests__/integration/persistence.test.d.ts.map +1 -0
  95. package/dist/__tests__/integration/persistence.test.js +129 -0
  96. package/dist/__tests__/integration/persistence.test.js.map +1 -0
  97. package/dist/__tests__/integration/pipeline-templates-integration.test.d.ts +16 -0
  98. package/dist/__tests__/integration/pipeline-templates-integration.test.d.ts.map +1 -0
  99. package/dist/__tests__/integration/pipeline-templates-integration.test.js +171 -0
  100. package/dist/__tests__/integration/pipeline-templates-integration.test.js.map +1 -0
  101. package/dist/__tests__/integration/scenario-pipeline.test.d.ts +11 -0
  102. package/dist/__tests__/integration/scenario-pipeline.test.d.ts.map +1 -0
  103. package/dist/__tests__/integration/scenario-pipeline.test.js +243 -0
  104. package/dist/__tests__/integration/scenario-pipeline.test.js.map +1 -0
  105. package/dist/__tests__/integration/stylesheet-application.test.d.ts +12 -0
  106. package/dist/__tests__/integration/stylesheet-application.test.d.ts.map +1 -0
  107. package/dist/__tests__/integration/stylesheet-application.test.js +119 -0
  108. package/dist/__tests__/integration/stylesheet-application.test.js.map +1 -0
  109. package/dist/__tests__/integration/subgraph-execution.test.d.ts +24 -0
  110. package/dist/__tests__/integration/subgraph-execution.test.d.ts.map +1 -0
  111. package/dist/__tests__/integration/subgraph-execution.test.js +291 -0
  112. package/dist/__tests__/integration/subgraph-execution.test.js.map +1 -0
  113. package/dist/__tests__/integration/validation-errors.test.d.ts +8 -0
  114. package/dist/__tests__/integration/validation-errors.test.d.ts.map +1 -0
  115. package/dist/__tests__/integration/validation-errors.test.js +150 -0
  116. package/dist/__tests__/integration/validation-errors.test.js.map +1 -0
  117. package/dist/agent/__tests__/loop-detection.test.d.ts +2 -0
  118. package/dist/agent/__tests__/loop-detection.test.d.ts.map +1 -0
  119. package/dist/agent/__tests__/loop-detection.test.js +236 -0
  120. package/dist/agent/__tests__/loop-detection.test.js.map +1 -0
  121. package/dist/agent/__tests__/loop.test.d.ts +2 -0
  122. package/dist/agent/__tests__/loop.test.d.ts.map +1 -0
  123. package/dist/agent/__tests__/loop.test.js +868 -0
  124. package/dist/agent/__tests__/loop.test.js.map +1 -0
  125. package/dist/agent/__tests__/truncation.test.d.ts +2 -0
  126. package/dist/agent/__tests__/truncation.test.d.ts.map +1 -0
  127. package/dist/agent/__tests__/truncation.test.js +276 -0
  128. package/dist/agent/__tests__/truncation.test.js.map +1 -0
  129. package/dist/agent/index.d.ts +11 -0
  130. package/dist/agent/index.d.ts.map +1 -0
  131. package/dist/agent/index.js +13 -0
  132. package/dist/agent/index.js.map +1 -0
  133. package/dist/agent/loop-detection.d.ts +21 -0
  134. package/dist/agent/loop-detection.d.ts.map +1 -0
  135. package/dist/agent/loop-detection.js +61 -0
  136. package/dist/agent/loop-detection.js.map +1 -0
  137. package/dist/agent/loop.d.ts +88 -0
  138. package/dist/agent/loop.d.ts.map +1 -0
  139. package/dist/agent/loop.js +411 -0
  140. package/dist/agent/loop.js.map +1 -0
  141. package/dist/agent/tools/__tests__/anthropic-tools.test.d.ts +6 -0
  142. package/dist/agent/tools/__tests__/anthropic-tools.test.d.ts.map +1 -0
  143. package/dist/agent/tools/__tests__/anthropic-tools.test.js +49 -0
  144. package/dist/agent/tools/__tests__/anthropic-tools.test.js.map +1 -0
  145. package/dist/agent/tools/__tests__/environment.test.d.ts +6 -0
  146. package/dist/agent/tools/__tests__/environment.test.d.ts.map +1 -0
  147. package/dist/agent/tools/__tests__/environment.test.js +33 -0
  148. package/dist/agent/tools/__tests__/environment.test.js.map +1 -0
  149. package/dist/agent/tools/__tests__/gemini-tools.test.d.ts +6 -0
  150. package/dist/agent/tools/__tests__/gemini-tools.test.d.ts.map +1 -0
  151. package/dist/agent/tools/__tests__/gemini-tools.test.js +98 -0
  152. package/dist/agent/tools/__tests__/gemini-tools.test.js.map +1 -0
  153. package/dist/agent/tools/__tests__/openai-tools.test.d.ts +6 -0
  154. package/dist/agent/tools/__tests__/openai-tools.test.d.ts.map +1 -0
  155. package/dist/agent/tools/__tests__/openai-tools.test.js +53 -0
  156. package/dist/agent/tools/__tests__/openai-tools.test.js.map +1 -0
  157. package/dist/agent/tools/__tests__/patch.test.d.ts +6 -0
  158. package/dist/agent/tools/__tests__/patch.test.d.ts.map +1 -0
  159. package/dist/agent/tools/__tests__/patch.test.js +116 -0
  160. package/dist/agent/tools/__tests__/patch.test.js.map +1 -0
  161. package/dist/agent/tools/__tests__/profiles.test.d.ts +6 -0
  162. package/dist/agent/tools/__tests__/profiles.test.d.ts.map +1 -0
  163. package/dist/agent/tools/__tests__/profiles.test.js +125 -0
  164. package/dist/agent/tools/__tests__/profiles.test.js.map +1 -0
  165. package/dist/agent/tools/__tests__/registry.test.d.ts +6 -0
  166. package/dist/agent/tools/__tests__/registry.test.d.ts.map +1 -0
  167. package/dist/agent/tools/__tests__/registry.test.js +94 -0
  168. package/dist/agent/tools/__tests__/registry.test.js.map +1 -0
  169. package/dist/agent/tools/__tests__/shared.test.d.ts +6 -0
  170. package/dist/agent/tools/__tests__/shared.test.d.ts.map +1 -0
  171. package/dist/agent/tools/__tests__/shared.test.js +131 -0
  172. package/dist/agent/tools/__tests__/shared.test.js.map +1 -0
  173. package/dist/agent/tools/anthropic-tools.d.ts +15 -0
  174. package/dist/agent/tools/anthropic-tools.d.ts.map +1 -0
  175. package/dist/agent/tools/anthropic-tools.js +45 -0
  176. package/dist/agent/tools/anthropic-tools.js.map +1 -0
  177. package/dist/agent/tools/environment.d.ts +11 -0
  178. package/dist/agent/tools/environment.d.ts.map +1 -0
  179. package/dist/agent/tools/environment.js +35 -0
  180. package/dist/agent/tools/environment.js.map +1 -0
  181. package/dist/agent/tools/gemini-tools.d.ts +29 -0
  182. package/dist/agent/tools/gemini-tools.d.ts.map +1 -0
  183. package/dist/agent/tools/gemini-tools.js +112 -0
  184. package/dist/agent/tools/gemini-tools.js.map +1 -0
  185. package/dist/agent/tools/index.d.ts +13 -0
  186. package/dist/agent/tools/index.d.ts.map +1 -0
  187. package/dist/agent/tools/index.js +13 -0
  188. package/dist/agent/tools/index.js.map +1 -0
  189. package/dist/agent/tools/openai-tools.d.ts +18 -0
  190. package/dist/agent/tools/openai-tools.d.ts.map +1 -0
  191. package/dist/agent/tools/openai-tools.js +208 -0
  192. package/dist/agent/tools/openai-tools.js.map +1 -0
  193. package/dist/agent/tools/profiles.d.ts +66 -0
  194. package/dist/agent/tools/profiles.d.ts.map +1 -0
  195. package/dist/agent/tools/profiles.js +121 -0
  196. package/dist/agent/tools/profiles.js.map +1 -0
  197. package/dist/agent/tools/registry.d.ts +16 -0
  198. package/dist/agent/tools/registry.d.ts.map +1 -0
  199. package/dist/agent/tools/registry.js +55 -0
  200. package/dist/agent/tools/registry.js.map +1 -0
  201. package/dist/agent/tools/shared.d.ts +10 -0
  202. package/dist/agent/tools/shared.d.ts.map +1 -0
  203. package/dist/agent/tools/shared.js +207 -0
  204. package/dist/agent/tools/shared.js.map +1 -0
  205. package/dist/agent/tools/types.d.ts +55 -0
  206. package/dist/agent/tools/types.d.ts.map +1 -0
  207. package/dist/agent/tools/types.js +14 -0
  208. package/dist/agent/tools/types.js.map +1 -0
  209. package/dist/agent/truncation.d.ts +29 -0
  210. package/dist/agent/truncation.d.ts.map +1 -0
  211. package/dist/agent/truncation.js +76 -0
  212. package/dist/agent/truncation.js.map +1 -0
  213. package/dist/agent/types.d.ts +91 -0
  214. package/dist/agent/types.d.ts.map +1 -0
  215. package/dist/agent/types.js +45 -0
  216. package/dist/agent/types.js.map +1 -0
  217. package/dist/backend/__tests__/direct-backend.test.d.ts +14 -0
  218. package/dist/backend/__tests__/direct-backend.test.d.ts.map +1 -0
  219. package/dist/backend/__tests__/direct-backend.test.js +393 -0
  220. package/dist/backend/__tests__/direct-backend.test.js.map +1 -0
  221. package/dist/backend/__tests__/direct-bootstrap.test.d.ts +7 -0
  222. package/dist/backend/__tests__/direct-bootstrap.test.d.ts.map +1 -0
  223. package/dist/backend/__tests__/direct-bootstrap.test.js +177 -0
  224. package/dist/backend/__tests__/direct-bootstrap.test.js.map +1 -0
  225. package/dist/backend/__tests__/mock-backend.test.d.ts +7 -0
  226. package/dist/backend/__tests__/mock-backend.test.d.ts.map +1 -0
  227. package/dist/backend/__tests__/mock-backend.test.js +273 -0
  228. package/dist/backend/__tests__/mock-backend.test.js.map +1 -0
  229. package/dist/backend/__tests__/parity.test.d.ts +17 -0
  230. package/dist/backend/__tests__/parity.test.d.ts.map +1 -0
  231. package/dist/backend/__tests__/parity.test.js +411 -0
  232. package/dist/backend/__tests__/parity.test.js.map +1 -0
  233. package/dist/backend/direct-backend.d.ts +27 -0
  234. package/dist/backend/direct-backend.d.ts.map +1 -0
  235. package/dist/backend/direct-backend.js +76 -0
  236. package/dist/backend/direct-backend.js.map +1 -0
  237. package/dist/backend/direct-bootstrap.d.ts +29 -0
  238. package/dist/backend/direct-bootstrap.d.ts.map +1 -0
  239. package/dist/backend/direct-bootstrap.js +109 -0
  240. package/dist/backend/direct-bootstrap.js.map +1 -0
  241. package/dist/backend/index.d.ts +11 -0
  242. package/dist/backend/index.d.ts.map +1 -0
  243. package/dist/backend/index.js +8 -0
  244. package/dist/backend/index.js.map +1 -0
  245. package/dist/backend/mock-backend.d.ts +49 -0
  246. package/dist/backend/mock-backend.d.ts.map +1 -0
  247. package/dist/backend/mock-backend.js +87 -0
  248. package/dist/backend/mock-backend.js.map +1 -0
  249. package/dist/backend/types.d.ts +74 -0
  250. package/dist/backend/types.d.ts.map +1 -0
  251. package/dist/backend/types.js +12 -0
  252. package/dist/backend/types.js.map +1 -0
  253. package/dist/config.d.ts +196 -0
  254. package/dist/config.d.ts.map +1 -0
  255. package/dist/config.js +140 -0
  256. package/dist/config.js.map +1 -0
  257. package/dist/context/__tests__/auto-summarizer.test.d.ts +14 -0
  258. package/dist/context/__tests__/auto-summarizer.test.d.ts.map +1 -0
  259. package/dist/context/__tests__/auto-summarizer.test.js +189 -0
  260. package/dist/context/__tests__/auto-summarizer.test.js.map +1 -0
  261. package/dist/context/__tests__/context-cli-command.test.d.ts +7 -0
  262. package/dist/context/__tests__/context-cli-command.test.d.ts.map +1 -0
  263. package/dist/context/__tests__/context-cli-command.test.js +331 -0
  264. package/dist/context/__tests__/context-cli-command.test.js.map +1 -0
  265. package/dist/context/__tests__/pyramid-summary-integration.test.d.ts +2 -0
  266. package/dist/context/__tests__/pyramid-summary-integration.test.d.ts.map +1 -0
  267. package/dist/context/__tests__/pyramid-summary-integration.test.js +533 -0
  268. package/dist/context/__tests__/pyramid-summary-integration.test.js.map +1 -0
  269. package/dist/context/__tests__/summarizer.test.d.ts +2 -0
  270. package/dist/context/__tests__/summarizer.test.d.ts.map +1 -0
  271. package/dist/context/__tests__/summarizer.test.js +189 -0
  272. package/dist/context/__tests__/summarizer.test.js.map +1 -0
  273. package/dist/context/__tests__/summary-cache.test.d.ts +2 -0
  274. package/dist/context/__tests__/summary-cache.test.d.ts.map +1 -0
  275. package/dist/context/__tests__/summary-cache.test.js +214 -0
  276. package/dist/context/__tests__/summary-cache.test.js.map +1 -0
  277. package/dist/context/__tests__/summary-metrics.test.d.ts +2 -0
  278. package/dist/context/__tests__/summary-metrics.test.d.ts.map +1 -0
  279. package/dist/context/__tests__/summary-metrics.test.js +172 -0
  280. package/dist/context/__tests__/summary-metrics.test.js.map +1 -0
  281. package/dist/context/__tests__/summary-types.test.d.ts +2 -0
  282. package/dist/context/__tests__/summary-types.test.d.ts.map +1 -0
  283. package/dist/context/__tests__/summary-types.test.js +130 -0
  284. package/dist/context/__tests__/summary-types.test.js.map +1 -0
  285. package/dist/context/auto-summarizer.d.ts +120 -0
  286. package/dist/context/auto-summarizer.d.ts.map +1 -0
  287. package/dist/context/auto-summarizer.js +91 -0
  288. package/dist/context/auto-summarizer.js.map +1 -0
  289. package/dist/context/cli-command.d.ts +109 -0
  290. package/dist/context/cli-command.d.ts.map +1 -0
  291. package/dist/context/cli-command.js +382 -0
  292. package/dist/context/cli-command.js.map +1 -0
  293. package/dist/context/index.d.ts +8 -0
  294. package/dist/context/index.d.ts.map +1 -0
  295. package/dist/context/index.js +8 -0
  296. package/dist/context/index.js.map +1 -0
  297. package/dist/context/summarizer.d.ts +12 -0
  298. package/dist/context/summarizer.d.ts.map +1 -0
  299. package/dist/context/summarizer.js +105 -0
  300. package/dist/context/summarizer.js.map +1 -0
  301. package/dist/context/summary-cache.d.ts +41 -0
  302. package/dist/context/summary-cache.d.ts.map +1 -0
  303. package/dist/context/summary-cache.js +80 -0
  304. package/dist/context/summary-cache.js.map +1 -0
  305. package/dist/context/summary-engine.d.ts +46 -0
  306. package/dist/context/summary-engine.d.ts.map +1 -0
  307. package/dist/context/summary-engine.js +2 -0
  308. package/dist/context/summary-engine.js.map +1 -0
  309. package/dist/context/summary-metrics.d.ts +75 -0
  310. package/dist/context/summary-metrics.d.ts.map +1 -0
  311. package/dist/context/summary-metrics.js +160 -0
  312. package/dist/context/summary-metrics.js.map +1 -0
  313. package/dist/context/summary-types.d.ts +103 -0
  314. package/dist/context/summary-types.d.ts.map +1 -0
  315. package/dist/context/summary-types.js +39 -0
  316. package/dist/context/summary-types.js.map +1 -0
  317. package/dist/convergence/__tests__/budget.test.d.ts +6 -0
  318. package/dist/convergence/__tests__/budget.test.d.ts.map +1 -0
  319. package/dist/convergence/__tests__/budget.test.js +187 -0
  320. package/dist/convergence/__tests__/budget.test.js.map +1 -0
  321. package/dist/convergence/__tests__/controller.test.d.ts +9 -0
  322. package/dist/convergence/__tests__/controller.test.d.ts.map +1 -0
  323. package/dist/convergence/__tests__/controller.test.js +585 -0
  324. package/dist/convergence/__tests__/controller.test.js.map +1 -0
  325. package/dist/convergence/__tests__/dual-signal.test.d.ts +14 -0
  326. package/dist/convergence/__tests__/dual-signal.test.d.ts.map +1 -0
  327. package/dist/convergence/__tests__/dual-signal.test.js +123 -0
  328. package/dist/convergence/__tests__/dual-signal.test.js.map +1 -0
  329. package/dist/convergence/__tests__/epic46-integration.test.d.ts +15 -0
  330. package/dist/convergence/__tests__/epic46-integration.test.d.ts.map +1 -0
  331. package/dist/convergence/__tests__/epic46-integration.test.js +522 -0
  332. package/dist/convergence/__tests__/epic46-integration.test.js.map +1 -0
  333. package/dist/convergence/__tests__/plateau.test.d.ts +6 -0
  334. package/dist/convergence/__tests__/plateau.test.d.ts.map +1 -0
  335. package/dist/convergence/__tests__/plateau.test.js +163 -0
  336. package/dist/convergence/__tests__/plateau.test.js.map +1 -0
  337. package/dist/convergence/__tests__/remediation.test.d.ts +11 -0
  338. package/dist/convergence/__tests__/remediation.test.d.ts.map +1 -0
  339. package/dist/convergence/__tests__/remediation.test.js +209 -0
  340. package/dist/convergence/__tests__/remediation.test.js.map +1 -0
  341. package/dist/convergence/__tests__/scenario-primary.test.d.ts +13 -0
  342. package/dist/convergence/__tests__/scenario-primary.test.d.ts.map +1 -0
  343. package/dist/convergence/__tests__/scenario-primary.test.js +183 -0
  344. package/dist/convergence/__tests__/scenario-primary.test.js.map +1 -0
  345. package/dist/convergence/budget.d.ts +181 -0
  346. package/dist/convergence/budget.d.ts.map +1 -0
  347. package/dist/convergence/budget.js +218 -0
  348. package/dist/convergence/budget.js.map +1 -0
  349. package/dist/convergence/controller.d.ts +133 -0
  350. package/dist/convergence/controller.d.ts.map +1 -0
  351. package/dist/convergence/controller.js +102 -0
  352. package/dist/convergence/controller.js.map +1 -0
  353. package/dist/convergence/dual-signal.d.ts +73 -0
  354. package/dist/convergence/dual-signal.d.ts.map +1 -0
  355. package/dist/convergence/dual-signal.js +78 -0
  356. package/dist/convergence/dual-signal.js.map +1 -0
  357. package/dist/convergence/index.d.ts +17 -0
  358. package/dist/convergence/index.d.ts.map +1 -0
  359. package/dist/convergence/index.js +11 -0
  360. package/dist/convergence/index.js.map +1 -0
  361. package/dist/convergence/plateau.d.ts +99 -0
  362. package/dist/convergence/plateau.d.ts.map +1 -0
  363. package/dist/convergence/plateau.js +83 -0
  364. package/dist/convergence/plateau.js.map +1 -0
  365. package/dist/convergence/remediation.d.ts +105 -0
  366. package/dist/convergence/remediation.d.ts.map +1 -0
  367. package/dist/convergence/remediation.js +117 -0
  368. package/dist/convergence/remediation.js.map +1 -0
  369. package/dist/events.d.ts +331 -0
  370. package/dist/events.d.ts.map +1 -0
  371. package/dist/events.js +13 -0
  372. package/dist/events.js.map +1 -0
  373. package/dist/factory-command.d.ts +40 -0
  374. package/dist/factory-command.d.ts.map +1 -0
  375. package/dist/factory-command.js +626 -0
  376. package/dist/factory-command.js.map +1 -0
  377. package/dist/factory-command.test.d.ts +8 -0
  378. package/dist/factory-command.test.d.ts.map +1 -0
  379. package/dist/factory-command.test.js +304 -0
  380. package/dist/factory-command.test.js.map +1 -0
  381. package/dist/graph/__tests__/attractor-compliance.test.d.ts +10 -0
  382. package/dist/graph/__tests__/attractor-compliance.test.d.ts.map +1 -0
  383. package/dist/graph/__tests__/attractor-compliance.test.js +766 -0
  384. package/dist/graph/__tests__/attractor-compliance.test.js.map +1 -0
  385. package/dist/graph/__tests__/checkpoint.test.d.ts +8 -0
  386. package/dist/graph/__tests__/checkpoint.test.d.ts.map +1 -0
  387. package/dist/graph/__tests__/checkpoint.test.js +329 -0
  388. package/dist/graph/__tests__/checkpoint.test.js.map +1 -0
  389. package/dist/graph/__tests__/condition-parser.test.d.ts +14 -0
  390. package/dist/graph/__tests__/condition-parser.test.d.ts.map +1 -0
  391. package/dist/graph/__tests__/condition-parser.test.js +406 -0
  392. package/dist/graph/__tests__/condition-parser.test.js.map +1 -0
  393. package/dist/graph/__tests__/context.test.d.ts +14 -0
  394. package/dist/graph/__tests__/context.test.d.ts.map +1 -0
  395. package/dist/graph/__tests__/context.test.js +276 -0
  396. package/dist/graph/__tests__/context.test.js.map +1 -0
  397. package/dist/graph/__tests__/edge-selector-events.test.d.ts +11 -0
  398. package/dist/graph/__tests__/edge-selector-events.test.d.ts.map +1 -0
  399. package/dist/graph/__tests__/edge-selector-events.test.js +184 -0
  400. package/dist/graph/__tests__/edge-selector-events.test.js.map +1 -0
  401. package/dist/graph/__tests__/edge-selector.test.d.ts +6 -0
  402. package/dist/graph/__tests__/edge-selector.test.d.ts.map +1 -0
  403. package/dist/graph/__tests__/edge-selector.test.js +452 -0
  404. package/dist/graph/__tests__/edge-selector.test.js.map +1 -0
  405. package/dist/graph/__tests__/executor-convergence.test.d.ts +12 -0
  406. package/dist/graph/__tests__/executor-convergence.test.d.ts.map +1 -0
  407. package/dist/graph/__tests__/executor-convergence.test.js +432 -0
  408. package/dist/graph/__tests__/executor-convergence.test.js.map +1 -0
  409. package/dist/graph/__tests__/executor-fidelity.test.d.ts +13 -0
  410. package/dist/graph/__tests__/executor-fidelity.test.d.ts.map +1 -0
  411. package/dist/graph/__tests__/executor-fidelity.test.js +335 -0
  412. package/dist/graph/__tests__/executor-fidelity.test.js.map +1 -0
  413. package/dist/graph/__tests__/executor.test.d.ts +14 -0
  414. package/dist/graph/__tests__/executor.test.d.ts.map +1 -0
  415. package/dist/graph/__tests__/executor.test.js +901 -0
  416. package/dist/graph/__tests__/executor.test.js.map +1 -0
  417. package/dist/graph/__tests__/fidelity.test.d.ts +8 -0
  418. package/dist/graph/__tests__/fidelity.test.d.ts.map +1 -0
  419. package/dist/graph/__tests__/fidelity.test.js +135 -0
  420. package/dist/graph/__tests__/fidelity.test.js.map +1 -0
  421. package/dist/graph/__tests__/llm-evaluator.test.d.ts +7 -0
  422. package/dist/graph/__tests__/llm-evaluator.test.d.ts.map +1 -0
  423. package/dist/graph/__tests__/llm-evaluator.test.js +106 -0
  424. package/dist/graph/__tests__/llm-evaluator.test.js.map +1 -0
  425. package/dist/graph/__tests__/parser-chaining.test.d.ts +13 -0
  426. package/dist/graph/__tests__/parser-chaining.test.d.ts.map +1 -0
  427. package/dist/graph/__tests__/parser-chaining.test.js +215 -0
  428. package/dist/graph/__tests__/parser-chaining.test.js.map +1 -0
  429. package/dist/graph/__tests__/parser.test.d.ts +22 -0
  430. package/dist/graph/__tests__/parser.test.d.ts.map +1 -0
  431. package/dist/graph/__tests__/parser.test.js +452 -0
  432. package/dist/graph/__tests__/parser.test.js.map +1 -0
  433. package/dist/graph/__tests__/run-state.test.d.ts +13 -0
  434. package/dist/graph/__tests__/run-state.test.d.ts.map +1 -0
  435. package/dist/graph/__tests__/run-state.test.js +189 -0
  436. package/dist/graph/__tests__/run-state.test.js.map +1 -0
  437. package/dist/graph/__tests__/transformer.test.d.ts +16 -0
  438. package/dist/graph/__tests__/transformer.test.d.ts.map +1 -0
  439. package/dist/graph/__tests__/transformer.test.js +350 -0
  440. package/dist/graph/__tests__/transformer.test.js.map +1 -0
  441. package/dist/graph/__tests__/validator-errors.test.d.ts +15 -0
  442. package/dist/graph/__tests__/validator-errors.test.d.ts.map +1 -0
  443. package/dist/graph/__tests__/validator-errors.test.js +572 -0
  444. package/dist/graph/__tests__/validator-errors.test.js.map +1 -0
  445. package/dist/graph/__tests__/validator-warnings.test.d.ts +15 -0
  446. package/dist/graph/__tests__/validator-warnings.test.d.ts.map +1 -0
  447. package/dist/graph/__tests__/validator-warnings.test.js +363 -0
  448. package/dist/graph/__tests__/validator-warnings.test.js.map +1 -0
  449. package/dist/graph/checkpoint.d.ts +61 -0
  450. package/dist/graph/checkpoint.d.ts.map +1 -0
  451. package/dist/graph/checkpoint.js +80 -0
  452. package/dist/graph/checkpoint.js.map +1 -0
  453. package/dist/graph/condition-parser.d.ts +55 -0
  454. package/dist/graph/condition-parser.d.ts.map +1 -0
  455. package/dist/graph/condition-parser.js +213 -0
  456. package/dist/graph/condition-parser.js.map +1 -0
  457. package/dist/graph/context.d.ts +53 -0
  458. package/dist/graph/context.d.ts.map +1 -0
  459. package/dist/graph/context.js +90 -0
  460. package/dist/graph/context.js.map +1 -0
  461. package/dist/graph/edge-selector.d.ts +74 -0
  462. package/dist/graph/edge-selector.d.ts.map +1 -0
  463. package/dist/graph/edge-selector.js +178 -0
  464. package/dist/graph/edge-selector.js.map +1 -0
  465. package/dist/graph/executor.d.ts +133 -0
  466. package/dist/graph/executor.d.ts.map +1 -0
  467. package/dist/graph/executor.js +787 -0
  468. package/dist/graph/executor.js.map +1 -0
  469. package/dist/graph/fidelity.d.ts +27 -0
  470. package/dist/graph/fidelity.d.ts.map +1 -0
  471. package/dist/graph/fidelity.js +38 -0
  472. package/dist/graph/fidelity.js.map +1 -0
  473. package/dist/graph/index.d.ts +13 -0
  474. package/dist/graph/index.d.ts.map +1 -0
  475. package/dist/graph/index.js +9 -0
  476. package/dist/graph/index.js.map +1 -0
  477. package/dist/graph/llm-evaluator.d.ts +61 -0
  478. package/dist/graph/llm-evaluator.d.ts.map +1 -0
  479. package/dist/graph/llm-evaluator.js +106 -0
  480. package/dist/graph/llm-evaluator.js.map +1 -0
  481. package/dist/graph/parser.d.ts +28 -0
  482. package/dist/graph/parser.d.ts.map +1 -0
  483. package/dist/graph/parser.js +370 -0
  484. package/dist/graph/parser.js.map +1 -0
  485. package/dist/graph/rules/error-rules.d.ts +19 -0
  486. package/dist/graph/rules/error-rules.d.ts.map +1 -0
  487. package/dist/graph/rules/error-rules.js +264 -0
  488. package/dist/graph/rules/error-rules.js.map +1 -0
  489. package/dist/graph/rules/warning-rules.d.ts +7 -0
  490. package/dist/graph/rules/warning-rules.d.ts.map +1 -0
  491. package/dist/graph/rules/warning-rules.js +165 -0
  492. package/dist/graph/rules/warning-rules.js.map +1 -0
  493. package/dist/graph/run-state.d.ts +62 -0
  494. package/dist/graph/run-state.d.ts.map +1 -0
  495. package/dist/graph/run-state.js +79 -0
  496. package/dist/graph/run-state.js.map +1 -0
  497. package/dist/graph/transformer.d.ts +31 -0
  498. package/dist/graph/transformer.d.ts.map +1 -0
  499. package/dist/graph/transformer.js +64 -0
  500. package/dist/graph/transformer.js.map +1 -0
  501. package/dist/graph/types.d.ts +320 -0
  502. package/dist/graph/types.d.ts.map +1 -0
  503. package/dist/graph/types.js +6 -0
  504. package/dist/graph/types.js.map +1 -0
  505. package/dist/graph/validator.d.ts +16 -0
  506. package/dist/graph/validator.d.ts.map +1 -0
  507. package/dist/graph/validator.js +40 -0
  508. package/dist/graph/validator.js.map +1 -0
  509. package/dist/handlers/__tests__/codergen-handler.test.d.ts +14 -0
  510. package/dist/handlers/__tests__/codergen-handler.test.d.ts.map +1 -0
  511. package/dist/handlers/__tests__/codergen-handler.test.js +442 -0
  512. package/dist/handlers/__tests__/codergen-handler.test.js.map +1 -0
  513. package/dist/handlers/__tests__/fan-in.test.d.ts +14 -0
  514. package/dist/handlers/__tests__/fan-in.test.d.ts.map +1 -0
  515. package/dist/handlers/__tests__/fan-in.test.js +399 -0
  516. package/dist/handlers/__tests__/fan-in.test.js.map +1 -0
  517. package/dist/handlers/__tests__/join-policy.test.d.ts +9 -0
  518. package/dist/handlers/__tests__/join-policy.test.d.ts.map +1 -0
  519. package/dist/handlers/__tests__/join-policy.test.js +201 -0
  520. package/dist/handlers/__tests__/join-policy.test.js.map +1 -0
  521. package/dist/handlers/__tests__/manager-loop.test.d.ts +14 -0
  522. package/dist/handlers/__tests__/manager-loop.test.d.ts.map +1 -0
  523. package/dist/handlers/__tests__/manager-loop.test.js +322 -0
  524. package/dist/handlers/__tests__/manager-loop.test.js.map +1 -0
  525. package/dist/handlers/__tests__/parallel-events.test.d.ts +12 -0
  526. package/dist/handlers/__tests__/parallel-events.test.d.ts.map +1 -0
  527. package/dist/handlers/__tests__/parallel-events.test.js +252 -0
  528. package/dist/handlers/__tests__/parallel-events.test.js.map +1 -0
  529. package/dist/handlers/__tests__/parallel-handler.test.d.ts +14 -0
  530. package/dist/handlers/__tests__/parallel-handler.test.d.ts.map +1 -0
  531. package/dist/handlers/__tests__/parallel-handler.test.js +337 -0
  532. package/dist/handlers/__tests__/parallel-handler.test.js.map +1 -0
  533. package/dist/handlers/__tests__/parallel-join.test.d.ts +9 -0
  534. package/dist/handlers/__tests__/parallel-join.test.d.ts.map +1 -0
  535. package/dist/handlers/__tests__/parallel-join.test.js +267 -0
  536. package/dist/handlers/__tests__/parallel-join.test.js.map +1 -0
  537. package/dist/handlers/__tests__/registry.test.d.ts +14 -0
  538. package/dist/handlers/__tests__/registry.test.d.ts.map +1 -0
  539. package/dist/handlers/__tests__/registry.test.js +315 -0
  540. package/dist/handlers/__tests__/registry.test.js.map +1 -0
  541. package/dist/handlers/__tests__/subgraph-events.test.d.ts +10 -0
  542. package/dist/handlers/__tests__/subgraph-events.test.d.ts.map +1 -0
  543. package/dist/handlers/__tests__/subgraph-events.test.js +189 -0
  544. package/dist/handlers/__tests__/subgraph-events.test.js.map +1 -0
  545. package/dist/handlers/__tests__/subgraph-inheritance.test.d.ts +14 -0
  546. package/dist/handlers/__tests__/subgraph-inheritance.test.d.ts.map +1 -0
  547. package/dist/handlers/__tests__/subgraph-inheritance.test.js +267 -0
  548. package/dist/handlers/__tests__/subgraph-inheritance.test.js.map +1 -0
  549. package/dist/handlers/__tests__/subgraph.test.d.ts +14 -0
  550. package/dist/handlers/__tests__/subgraph.test.d.ts.map +1 -0
  551. package/dist/handlers/__tests__/subgraph.test.js +369 -0
  552. package/dist/handlers/__tests__/subgraph.test.js.map +1 -0
  553. package/dist/handlers/__tests__/tool-handler.test.d.ts +11 -0
  554. package/dist/handlers/__tests__/tool-handler.test.d.ts.map +1 -0
  555. package/dist/handlers/__tests__/tool-handler.test.js +184 -0
  556. package/dist/handlers/__tests__/tool-handler.test.js.map +1 -0
  557. package/dist/handlers/__tests__/tool-scenario.test.d.ts +12 -0
  558. package/dist/handlers/__tests__/tool-scenario.test.d.ts.map +1 -0
  559. package/dist/handlers/__tests__/tool-scenario.test.js +222 -0
  560. package/dist/handlers/__tests__/tool-scenario.test.js.map +1 -0
  561. package/dist/handlers/__tests__/wait-human-handler.test.d.ts +11 -0
  562. package/dist/handlers/__tests__/wait-human-handler.test.d.ts.map +1 -0
  563. package/dist/handlers/__tests__/wait-human-handler.test.js +251 -0
  564. package/dist/handlers/__tests__/wait-human-handler.test.js.map +1 -0
  565. package/dist/handlers/codergen-handler.d.ts +83 -0
  566. package/dist/handlers/codergen-handler.d.ts.map +1 -0
  567. package/dist/handlers/codergen-handler.js +152 -0
  568. package/dist/handlers/codergen-handler.js.map +1 -0
  569. package/dist/handlers/conditional.d.ts +15 -0
  570. package/dist/handlers/conditional.d.ts.map +1 -0
  571. package/dist/handlers/conditional.js +16 -0
  572. package/dist/handlers/conditional.js.map +1 -0
  573. package/dist/handlers/exit.d.ts +10 -0
  574. package/dist/handlers/exit.d.ts.map +1 -0
  575. package/dist/handlers/exit.js +11 -0
  576. package/dist/handlers/exit.js.map +1 -0
  577. package/dist/handlers/fan-in.d.ts +74 -0
  578. package/dist/handlers/fan-in.d.ts.map +1 -0
  579. package/dist/handlers/fan-in.js +191 -0
  580. package/dist/handlers/fan-in.js.map +1 -0
  581. package/dist/handlers/index.d.ts +29 -0
  582. package/dist/handlers/index.d.ts.map +1 -0
  583. package/dist/handlers/index.js +22 -0
  584. package/dist/handlers/index.js.map +1 -0
  585. package/dist/handlers/join-policy.d.ts +117 -0
  586. package/dist/handlers/join-policy.d.ts.map +1 -0
  587. package/dist/handlers/join-policy.js +129 -0
  588. package/dist/handlers/join-policy.js.map +1 -0
  589. package/dist/handlers/manager-loop.d.ts +54 -0
  590. package/dist/handlers/manager-loop.d.ts.map +1 -0
  591. package/dist/handlers/manager-loop.js +177 -0
  592. package/dist/handlers/manager-loop.js.map +1 -0
  593. package/dist/handlers/parallel.d.ts +31 -0
  594. package/dist/handlers/parallel.d.ts.map +1 -0
  595. package/dist/handlers/parallel.js +362 -0
  596. package/dist/handlers/parallel.js.map +1 -0
  597. package/dist/handlers/registry.d.ts +75 -0
  598. package/dist/handlers/registry.d.ts.map +1 -0
  599. package/dist/handlers/registry.js +132 -0
  600. package/dist/handlers/registry.js.map +1 -0
  601. package/dist/handlers/start.d.ts +10 -0
  602. package/dist/handlers/start.d.ts.map +1 -0
  603. package/dist/handlers/start.js +11 -0
  604. package/dist/handlers/start.js.map +1 -0
  605. package/dist/handlers/subgraph.d.ts +46 -0
  606. package/dist/handlers/subgraph.d.ts.map +1 -0
  607. package/dist/handlers/subgraph.js +178 -0
  608. package/dist/handlers/subgraph.js.map +1 -0
  609. package/dist/handlers/tool.d.ts +36 -0
  610. package/dist/handlers/tool.d.ts.map +1 -0
  611. package/dist/handlers/tool.js +99 -0
  612. package/dist/handlers/tool.js.map +1 -0
  613. package/dist/handlers/types.d.ts +98 -0
  614. package/dist/handlers/types.d.ts.map +1 -0
  615. package/dist/handlers/types.js +6 -0
  616. package/dist/handlers/types.js.map +1 -0
  617. package/dist/handlers/wait-human.d.ts +65 -0
  618. package/dist/handlers/wait-human.d.ts.map +1 -0
  619. package/dist/handlers/wait-human.js +124 -0
  620. package/dist/handlers/wait-human.js.map +1 -0
  621. package/dist/index.d.ts +24 -0
  622. package/dist/index.d.ts.map +1 -0
  623. package/dist/index.js +33 -0
  624. package/dist/index.js.map +1 -0
  625. package/dist/llm/__tests__/client.test.d.ts +2 -0
  626. package/dist/llm/__tests__/client.test.d.ts.map +1 -0
  627. package/dist/llm/__tests__/client.test.js +198 -0
  628. package/dist/llm/__tests__/client.test.js.map +1 -0
  629. package/dist/llm/__tests__/types.test.d.ts +2 -0
  630. package/dist/llm/__tests__/types.test.d.ts.map +1 -0
  631. package/dist/llm/__tests__/types.test.js +289 -0
  632. package/dist/llm/__tests__/types.test.js.map +1 -0
  633. package/dist/llm/client.d.ts +19 -0
  634. package/dist/llm/client.d.ts.map +1 -0
  635. package/dist/llm/client.js +50 -0
  636. package/dist/llm/client.js.map +1 -0
  637. package/dist/llm/index.d.ts +6 -0
  638. package/dist/llm/index.d.ts.map +1 -0
  639. package/dist/llm/index.js +6 -0
  640. package/dist/llm/index.js.map +1 -0
  641. package/dist/llm/middleware/__tests__/cost-tracking.test.d.ts +2 -0
  642. package/dist/llm/middleware/__tests__/cost-tracking.test.d.ts.map +1 -0
  643. package/dist/llm/middleware/__tests__/cost-tracking.test.js +73 -0
  644. package/dist/llm/middleware/__tests__/cost-tracking.test.js.map +1 -0
  645. package/dist/llm/middleware/__tests__/logging.test.d.ts +2 -0
  646. package/dist/llm/middleware/__tests__/logging.test.d.ts.map +1 -0
  647. package/dist/llm/middleware/__tests__/logging.test.js +127 -0
  648. package/dist/llm/middleware/__tests__/logging.test.js.map +1 -0
  649. package/dist/llm/middleware/__tests__/retry.test.d.ts +2 -0
  650. package/dist/llm/middleware/__tests__/retry.test.d.ts.map +1 -0
  651. package/dist/llm/middleware/__tests__/retry.test.js +126 -0
  652. package/dist/llm/middleware/__tests__/retry.test.js.map +1 -0
  653. package/dist/llm/middleware/cost-tracking.d.ts +8 -0
  654. package/dist/llm/middleware/cost-tracking.d.ts.map +1 -0
  655. package/dist/llm/middleware/cost-tracking.js +34 -0
  656. package/dist/llm/middleware/cost-tracking.js.map +1 -0
  657. package/dist/llm/middleware/index.d.ts +5 -0
  658. package/dist/llm/middleware/index.d.ts.map +1 -0
  659. package/dist/llm/middleware/index.js +6 -0
  660. package/dist/llm/middleware/index.js.map +1 -0
  661. package/dist/llm/middleware/logging.d.ts +6 -0
  662. package/dist/llm/middleware/logging.d.ts.map +1 -0
  663. package/dist/llm/middleware/logging.js +54 -0
  664. package/dist/llm/middleware/logging.js.map +1 -0
  665. package/dist/llm/middleware/retry.d.ts +14 -0
  666. package/dist/llm/middleware/retry.d.ts.map +1 -0
  667. package/dist/llm/middleware/retry.js +40 -0
  668. package/dist/llm/middleware/retry.js.map +1 -0
  669. package/dist/llm/middleware/types.d.ts +23 -0
  670. package/dist/llm/middleware/types.d.ts.map +1 -0
  671. package/dist/llm/middleware/types.js +24 -0
  672. package/dist/llm/middleware/types.js.map +1 -0
  673. package/dist/llm/model-registry.d.ts +14 -0
  674. package/dist/llm/model-registry.d.ts.map +1 -0
  675. package/dist/llm/model-registry.js +32 -0
  676. package/dist/llm/model-registry.js.map +1 -0
  677. package/dist/llm/providers/__tests__/anthropic.test.d.ts +2 -0
  678. package/dist/llm/providers/__tests__/anthropic.test.d.ts.map +1 -0
  679. package/dist/llm/providers/__tests__/anthropic.test.js +412 -0
  680. package/dist/llm/providers/__tests__/anthropic.test.js.map +1 -0
  681. package/dist/llm/providers/__tests__/gemini.test.d.ts +2 -0
  682. package/dist/llm/providers/__tests__/gemini.test.d.ts.map +1 -0
  683. package/dist/llm/providers/__tests__/gemini.test.js +591 -0
  684. package/dist/llm/providers/__tests__/gemini.test.js.map +1 -0
  685. package/dist/llm/providers/__tests__/openai.test.d.ts +2 -0
  686. package/dist/llm/providers/__tests__/openai.test.d.ts.map +1 -0
  687. package/dist/llm/providers/__tests__/openai.test.js +546 -0
  688. package/dist/llm/providers/__tests__/openai.test.js.map +1 -0
  689. package/dist/llm/providers/anthropic.d.ts +25 -0
  690. package/dist/llm/providers/anthropic.d.ts.map +1 -0
  691. package/dist/llm/providers/anthropic.js +315 -0
  692. package/dist/llm/providers/anthropic.js.map +1 -0
  693. package/dist/llm/providers/gemini.d.ts +28 -0
  694. package/dist/llm/providers/gemini.d.ts.map +1 -0
  695. package/dist/llm/providers/gemini.js +429 -0
  696. package/dist/llm/providers/gemini.js.map +1 -0
  697. package/dist/llm/providers/index.d.ts +7 -0
  698. package/dist/llm/providers/index.d.ts.map +1 -0
  699. package/dist/llm/providers/index.js +4 -0
  700. package/dist/llm/providers/index.js.map +1 -0
  701. package/dist/llm/providers/openai.d.ts +28 -0
  702. package/dist/llm/providers/openai.d.ts.map +1 -0
  703. package/dist/llm/providers/openai.js +426 -0
  704. package/dist/llm/providers/openai.js.map +1 -0
  705. package/dist/llm/types.d.ts +127 -0
  706. package/dist/llm/types.d.ts.map +1 -0
  707. package/dist/llm/types.js +21 -0
  708. package/dist/llm/types.js.map +1 -0
  709. package/dist/persistence/__tests__/factory-queries.test.d.ts +9 -0
  710. package/dist/persistence/__tests__/factory-queries.test.d.ts.map +1 -0
  711. package/dist/persistence/__tests__/factory-queries.test.js +372 -0
  712. package/dist/persistence/__tests__/factory-queries.test.js.map +1 -0
  713. package/dist/persistence/__tests__/factory-schema.test.d.ts +6 -0
  714. package/dist/persistence/__tests__/factory-schema.test.d.ts.map +1 -0
  715. package/dist/persistence/__tests__/factory-schema.test.js +105 -0
  716. package/dist/persistence/__tests__/factory-schema.test.js.map +1 -0
  717. package/dist/persistence/factory-queries.d.ts +204 -0
  718. package/dist/persistence/factory-queries.d.ts.map +1 -0
  719. package/dist/persistence/factory-queries.js +186 -0
  720. package/dist/persistence/factory-queries.js.map +1 -0
  721. package/dist/persistence/factory-schema.d.ts +16 -0
  722. package/dist/persistence/factory-schema.d.ts.map +1 -0
  723. package/dist/persistence/factory-schema.js +89 -0
  724. package/dist/persistence/factory-schema.js.map +1 -0
  725. package/dist/scenarios/__tests__/cli-command-list.test.d.ts +7 -0
  726. package/dist/scenarios/__tests__/cli-command-list.test.d.ts.map +1 -0
  727. package/dist/scenarios/__tests__/cli-command-list.test.js +237 -0
  728. package/dist/scenarios/__tests__/cli-command-list.test.js.map +1 -0
  729. package/dist/scenarios/__tests__/cli-command.test.d.ts +11 -0
  730. package/dist/scenarios/__tests__/cli-command.test.d.ts.map +1 -0
  731. package/dist/scenarios/__tests__/cli-command.test.js +275 -0
  732. package/dist/scenarios/__tests__/cli-command.test.js.map +1 -0
  733. package/dist/scenarios/__tests__/integrity-pipeline.test.d.ts +15 -0
  734. package/dist/scenarios/__tests__/integrity-pipeline.test.d.ts.map +1 -0
  735. package/dist/scenarios/__tests__/integrity-pipeline.test.js +318 -0
  736. package/dist/scenarios/__tests__/integrity-pipeline.test.js.map +1 -0
  737. package/dist/scenarios/__tests__/runner-twins.test.d.ts +13 -0
  738. package/dist/scenarios/__tests__/runner-twins.test.d.ts.map +1 -0
  739. package/dist/scenarios/__tests__/runner-twins.test.js +205 -0
  740. package/dist/scenarios/__tests__/runner-twins.test.js.map +1 -0
  741. package/dist/scenarios/__tests__/scorer.test.d.ts +11 -0
  742. package/dist/scenarios/__tests__/scorer.test.d.ts.map +1 -0
  743. package/dist/scenarios/__tests__/scorer.test.js +225 -0
  744. package/dist/scenarios/__tests__/scorer.test.js.map +1 -0
  745. package/dist/scenarios/__tests__/scoring-integration.test.d.ts +8 -0
  746. package/dist/scenarios/__tests__/scoring-integration.test.d.ts.map +1 -0
  747. package/dist/scenarios/__tests__/scoring-integration.test.js +178 -0
  748. package/dist/scenarios/__tests__/scoring-integration.test.js.map +1 -0
  749. package/dist/scenarios/__tests__/store.test.d.ts +5 -0
  750. package/dist/scenarios/__tests__/store.test.d.ts.map +1 -0
  751. package/dist/scenarios/__tests__/store.test.js +169 -0
  752. package/dist/scenarios/__tests__/store.test.js.map +1 -0
  753. package/dist/scenarios/cli-command.d.ts +20 -0
  754. package/dist/scenarios/cli-command.d.ts.map +1 -0
  755. package/dist/scenarios/cli-command.js +66 -0
  756. package/dist/scenarios/cli-command.js.map +1 -0
  757. package/dist/scenarios/index.d.ts +11 -0
  758. package/dist/scenarios/index.d.ts.map +1 -0
  759. package/dist/scenarios/index.js +11 -0
  760. package/dist/scenarios/index.js.map +1 -0
  761. package/dist/scenarios/runner.d.ts +64 -0
  762. package/dist/scenarios/runner.d.ts.map +1 -0
  763. package/dist/scenarios/runner.js +205 -0
  764. package/dist/scenarios/runner.js.map +1 -0
  765. package/dist/scenarios/scorer.d.ts +69 -0
  766. package/dist/scenarios/scorer.d.ts.map +1 -0
  767. package/dist/scenarios/scorer.js +66 -0
  768. package/dist/scenarios/scorer.js.map +1 -0
  769. package/dist/scenarios/store.d.ts +33 -0
  770. package/dist/scenarios/store.d.ts.map +1 -0
  771. package/dist/scenarios/store.js +92 -0
  772. package/dist/scenarios/store.js.map +1 -0
  773. package/dist/scenarios/types.d.ts +40 -0
  774. package/dist/scenarios/types.d.ts.map +1 -0
  775. package/dist/scenarios/types.js +5 -0
  776. package/dist/scenarios/types.js.map +1 -0
  777. package/dist/stylesheet/__tests__/stylesheet.test.d.ts +17 -0
  778. package/dist/stylesheet/__tests__/stylesheet.test.d.ts.map +1 -0
  779. package/dist/stylesheet/__tests__/stylesheet.test.js +368 -0
  780. package/dist/stylesheet/__tests__/stylesheet.test.js.map +1 -0
  781. package/dist/stylesheet/parser.d.ts +44 -0
  782. package/dist/stylesheet/parser.d.ts.map +1 -0
  783. package/dist/stylesheet/parser.js +190 -0
  784. package/dist/stylesheet/parser.js.map +1 -0
  785. package/dist/stylesheet/resolver.d.ts +38 -0
  786. package/dist/stylesheet/resolver.d.ts.map +1 -0
  787. package/dist/stylesheet/resolver.js +96 -0
  788. package/dist/stylesheet/resolver.js.map +1 -0
  789. package/dist/templates/__tests__/templates.test.d.ts +7 -0
  790. package/dist/templates/__tests__/templates.test.d.ts.map +1 -0
  791. package/dist/templates/__tests__/templates.test.js +92 -0
  792. package/dist/templates/__tests__/templates.test.js.map +1 -0
  793. package/dist/templates/index.d.ts +38 -0
  794. package/dist/templates/index.d.ts.map +1 -0
  795. package/dist/templates/index.js +153 -0
  796. package/dist/templates/index.js.map +1 -0
  797. package/dist/twins/__tests__/docker-compose.test.d.ts +13 -0
  798. package/dist/twins/__tests__/docker-compose.test.d.ts.map +1 -0
  799. package/dist/twins/__tests__/docker-compose.test.js +247 -0
  800. package/dist/twins/__tests__/docker-compose.test.js.map +1 -0
  801. package/dist/twins/__tests__/health-monitor.test.d.ts +19 -0
  802. package/dist/twins/__tests__/health-monitor.test.d.ts.map +1 -0
  803. package/dist/twins/__tests__/health-monitor.test.js +301 -0
  804. package/dist/twins/__tests__/health-monitor.test.js.map +1 -0
  805. package/dist/twins/__tests__/integration/e2e.test.d.ts +18 -0
  806. package/dist/twins/__tests__/integration/e2e.test.d.ts.map +1 -0
  807. package/dist/twins/__tests__/integration/e2e.test.js +146 -0
  808. package/dist/twins/__tests__/integration/e2e.test.js.map +1 -0
  809. package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts +16 -0
  810. package/dist/twins/__tests__/integration/health-monitor-integration.test.d.ts.map +1 -0
  811. package/dist/twins/__tests__/integration/health-monitor-integration.test.js +183 -0
  812. package/dist/twins/__tests__/integration/health-monitor-integration.test.js.map +1 -0
  813. package/dist/twins/__tests__/integration/helpers.d.ts +32 -0
  814. package/dist/twins/__tests__/integration/helpers.d.ts.map +1 -0
  815. package/dist/twins/__tests__/integration/helpers.js +67 -0
  816. package/dist/twins/__tests__/integration/helpers.js.map +1 -0
  817. package/dist/twins/__tests__/integration/lifecycle.test.d.ts +14 -0
  818. package/dist/twins/__tests__/integration/lifecycle.test.d.ts.map +1 -0
  819. package/dist/twins/__tests__/integration/lifecycle.test.js +127 -0
  820. package/dist/twins/__tests__/integration/lifecycle.test.js.map +1 -0
  821. package/dist/twins/__tests__/integration/persistence-integration.test.d.ts +14 -0
  822. package/dist/twins/__tests__/integration/persistence-integration.test.d.ts.map +1 -0
  823. package/dist/twins/__tests__/integration/persistence-integration.test.js +132 -0
  824. package/dist/twins/__tests__/integration/persistence-integration.test.js.map +1 -0
  825. package/dist/twins/__tests__/persistence.test.d.ts +10 -0
  826. package/dist/twins/__tests__/persistence.test.d.ts.map +1 -0
  827. package/dist/twins/__tests__/persistence.test.js +300 -0
  828. package/dist/twins/__tests__/persistence.test.js.map +1 -0
  829. package/dist/twins/__tests__/registry.test.d.ts +7 -0
  830. package/dist/twins/__tests__/registry.test.d.ts.map +1 -0
  831. package/dist/twins/__tests__/registry.test.js +282 -0
  832. package/dist/twins/__tests__/registry.test.js.map +1 -0
  833. package/dist/twins/__tests__/run-state.test.d.ts +9 -0
  834. package/dist/twins/__tests__/run-state.test.d.ts.map +1 -0
  835. package/dist/twins/__tests__/run-state.test.js +112 -0
  836. package/dist/twins/__tests__/run-state.test.js.map +1 -0
  837. package/dist/twins/__tests__/templates-cli.test.d.ts +10 -0
  838. package/dist/twins/__tests__/templates-cli.test.d.ts.map +1 -0
  839. package/dist/twins/__tests__/templates-cli.test.js +187 -0
  840. package/dist/twins/__tests__/templates-cli.test.js.map +1 -0
  841. package/dist/twins/__tests__/templates.test.d.ts +7 -0
  842. package/dist/twins/__tests__/templates.test.d.ts.map +1 -0
  843. package/dist/twins/__tests__/templates.test.js +87 -0
  844. package/dist/twins/__tests__/templates.test.js.map +1 -0
  845. package/dist/twins/__tests__/twins-cli.test.d.ts +11 -0
  846. package/dist/twins/__tests__/twins-cli.test.d.ts.map +1 -0
  847. package/dist/twins/__tests__/twins-cli.test.js +365 -0
  848. package/dist/twins/__tests__/twins-cli.test.js.map +1 -0
  849. package/dist/twins/docker-compose.d.ts +48 -0
  850. package/dist/twins/docker-compose.d.ts.map +1 -0
  851. package/dist/twins/docker-compose.js +172 -0
  852. package/dist/twins/docker-compose.js.map +1 -0
  853. package/dist/twins/health-monitor.d.ts +36 -0
  854. package/dist/twins/health-monitor.d.ts.map +1 -0
  855. package/dist/twins/health-monitor.js +114 -0
  856. package/dist/twins/health-monitor.js.map +1 -0
  857. package/dist/twins/index.d.ts +22 -0
  858. package/dist/twins/index.d.ts.map +1 -0
  859. package/dist/twins/index.js +19 -0
  860. package/dist/twins/index.js.map +1 -0
  861. package/dist/twins/persistence.d.ts +100 -0
  862. package/dist/twins/persistence.d.ts.map +1 -0
  863. package/dist/twins/persistence.js +120 -0
  864. package/dist/twins/persistence.js.map +1 -0
  865. package/dist/twins/registry.d.ts +40 -0
  866. package/dist/twins/registry.d.ts.map +1 -0
  867. package/dist/twins/registry.js +175 -0
  868. package/dist/twins/registry.js.map +1 -0
  869. package/dist/twins/run-state.d.ts +47 -0
  870. package/dist/twins/run-state.d.ts.map +1 -0
  871. package/dist/twins/run-state.js +70 -0
  872. package/dist/twins/run-state.js.map +1 -0
  873. package/dist/twins/schema.d.ts +40 -0
  874. package/dist/twins/schema.d.ts.map +1 -0
  875. package/dist/twins/schema.js +46 -0
  876. package/dist/twins/schema.js.map +1 -0
  877. package/dist/twins/templates.d.ts +27 -0
  878. package/dist/twins/templates.d.ts.map +1 -0
  879. package/dist/twins/templates.js +63 -0
  880. package/dist/twins/templates.js.map +1 -0
  881. package/dist/twins/types.d.ts +55 -0
  882. package/dist/twins/types.d.ts.map +1 -0
  883. package/dist/twins/types.js +26 -0
  884. package/dist/twins/types.js.map +1 -0
  885. package/package.json +28 -0
@@ -0,0 +1,787 @@
1
+ /**
2
+ * Graph executor — drives end-to-end traversal of a factory graph.
3
+ *
4
+ * Dispatches handlers, applies retry logic, writes checkpoints, selects edges,
5
+ * and emits FactoryEvents at each stage of execution.
6
+ *
7
+ * Story 42-14 (base executor).
8
+ * Story 42-16 (allowPartial demotion + ConvergenceController goal gate evaluation).
9
+ *
10
+ * NOTE: The executor uses `events.ts:Outcome` (StageStatus: 'SUCCESS' | 'FAIL' | ...)
11
+ * rather than `types.ts:Outcome` (OutcomeStatus: 'SUCCESS' | 'FAILURE' | ...) because:
12
+ * 1. The acceptance criteria specify status: 'FAIL' (from StageStatus, not OutcomeStatus)
13
+ * 2. All FactoryEvents payloads (graph:node-completed) use events.ts:Outcome
14
+ * NodeHandler returns types.ts:Outcome, which is cast via `as unknown as Outcome` where needed.
15
+ */
16
+ import path from 'node:path';
17
+ import { GraphContext } from './context.js';
18
+ import { selectEdge } from './edge-selector.js';
19
+ import { CheckpointManager } from './checkpoint.js';
20
+ import { RunStateManager } from './run-state.js';
21
+ import { createConvergenceController, SessionBudgetManager, PipelineBudgetManager, createPlateauDetector, checkPlateauAndEmit, buildRemediationContext, injectRemediationContext, computeBackoffDelay, createDualSignalCoordinator, CONTEXT_KEY_CODE_REVIEW_VERDICT, } from '../convergence/index.js';
22
+ import { computeSatisfactionScore } from '../scenarios/scorer.js';
23
+ import { upsertGraphRun, insertGraphNodeResult, insertScenarioResult } from '../persistence/factory-queries.js';
24
+ import { parseFidelityLevel, resolveFidelity } from './fidelity.js';
25
+ import { applyStylesheet } from './transformer.js';
26
+ // ---------------------------------------------------------------------------
27
+ // normalizeOutcomeStatus
28
+ // ---------------------------------------------------------------------------
29
+ /**
30
+ * Normalize a types.ts:Outcome (OutcomeStatus) to an events.ts:Outcome (StageStatus).
31
+ *
32
+ * NodeHandler returns `types.ts:Outcome` whose status is `OutcomeStatus`
33
+ * ('SUCCESS' | 'PARTIAL_SUCCESS' | 'FAILURE' | 'NEEDS_RETRY' | 'ESCALATE').
34
+ * The executor operates on `events.ts:Outcome` whose status is `StageStatus`
35
+ * ('SUCCESS' | 'FAIL' | 'PARTIAL_SUCCESS' | 'RETRY' | 'SKIPPED').
36
+ *
37
+ * Mapping:
38
+ * OutcomeStatus.FAILURE → StageStatus.FAIL
39
+ * OutcomeStatus.NEEDS_RETRY → StageStatus.FAIL (retry exhausted at this level)
40
+ * OutcomeStatus.ESCALATE → StageStatus.FAIL (treated as failure for routing)
41
+ * OutcomeStatus.SUCCESS → StageStatus.SUCCESS
42
+ * OutcomeStatus.PARTIAL_SUCCESS → StageStatus.PARTIAL_SUCCESS
43
+ */
44
+ function normalizeOutcomeStatus(raw) {
45
+ let status;
46
+ switch (raw.status) {
47
+ case 'SUCCESS':
48
+ status = 'SUCCESS';
49
+ break;
50
+ case 'PARTIAL_SUCCESS':
51
+ status = 'PARTIAL_SUCCESS';
52
+ break;
53
+ case 'FAILURE':
54
+ case 'NEEDS_RETRY':
55
+ case 'ESCALATE':
56
+ default:
57
+ status = 'FAIL';
58
+ break;
59
+ }
60
+ return {
61
+ ...raw,
62
+ status,
63
+ };
64
+ }
65
+ // ---------------------------------------------------------------------------
66
+ // dispatchWithRetry
67
+ // ---------------------------------------------------------------------------
68
+ /**
69
+ * Dispatch a node handler with exponential backoff retry on FAIL outcomes.
70
+ *
71
+ * Emits `graph:node-retried` before each retry attempt.
72
+ * Does NOT emit `graph:node-completed` or `graph:node-failed` — those are
73
+ * emitted by the main loop in `createGraphExecutor` AFTER the `allowPartial`
74
+ * demotion check, ensuring correct event semantics for demoted PARTIAL_SUCCESS.
75
+ *
76
+ * @param node - Node to dispatch (may have fidelity override applied).
77
+ * @param context - Current graph execution context.
78
+ * @param graph - The full factory graph.
79
+ * @param config - Executor configuration (handlerRegistry, eventBus, runId).
80
+ * @param nodeRetries - Mutable retry counter map; mutated in place.
81
+ * @returns The final Outcome after all retry attempts.
82
+ */
83
+ async function dispatchWithRetry(node, context, graph, config, nodeRetries) {
84
+ const maxRetries = node.maxRetries ?? 0;
85
+ const maxAttempts = maxRetries + 1;
86
+ let attempt = 0;
87
+ while (true) {
88
+ let outcome;
89
+ try {
90
+ const handler = config.handlerRegistry.resolve(node);
91
+ // NodeHandler returns types.ts:Outcome (OutcomeStatus).
92
+ // normalizeOutcomeStatus() maps to events.ts:Outcome (StageStatus) so that
93
+ // 'FAILURE' → 'FAIL', 'NEEDS_RETRY' → 'FAIL', 'ESCALATE' → 'FAIL',
94
+ // while 'SUCCESS' and 'PARTIAL_SUCCESS' pass through unchanged.
95
+ outcome = normalizeOutcomeStatus(await handler(node, context, graph));
96
+ }
97
+ catch (err) {
98
+ const msg = err instanceof Error ? err.message : String(err);
99
+ outcome = { status: 'FAIL', failureReason: msg };
100
+ }
101
+ const isFail = outcome.status === 'FAIL';
102
+ if (!isFail || attempt >= maxRetries) {
103
+ // Done: either succeeded or exhausted all retries.
104
+ // NOTE: event emission (graph:node-completed / graph:node-failed) is intentionally
105
+ // deferred to the main loop in createGraphExecutor, where it occurs AFTER the
106
+ // allowPartial demotion check. Emitting here would produce graph:node-completed
107
+ // for PARTIAL_SUCCESS outcomes that are subsequently demoted to FAIL (violating
108
+ // Dev Notes §"allow_partial Demotion — Placement in Executor").
109
+ return outcome;
110
+ }
111
+ // Retry path: increment counter, compute delay, emit event, await delay
112
+ nodeRetries[node.id] = (nodeRetries[node.id] ?? 0) + 1;
113
+ const delayMs = computeBackoffDelay(attempt);
114
+ config.eventBus?.emit('graph:node-retried', {
115
+ runId: config.runId,
116
+ nodeId: node.id,
117
+ attempt: attempt + 1, // 1-indexed: first retry = 1
118
+ maxAttempts,
119
+ delayMs,
120
+ });
121
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
122
+ attempt++;
123
+ }
124
+ }
125
+ // ---------------------------------------------------------------------------
126
+ // createGraphExecutor
127
+ // ---------------------------------------------------------------------------
128
+ /**
129
+ * Create a new graph executor instance.
130
+ *
131
+ * The returned executor's `run()` method drives a factory graph from start node
132
+ * to exit node (or resumes from a checkpoint if `config.checkpointPath` is set),
133
+ * dispatching handlers, applying retry logic, writing checkpoints, and emitting
134
+ * FactoryEvents for full observability.
135
+ */
136
+ export function createGraphExecutor() {
137
+ return {
138
+ async run(graph, config) {
139
+ // Apply model stylesheet to all nodes before any handler is dispatched.
140
+ // This is idempotent: nodes with explicit llmModel/llmProvider/reasoningEffort
141
+ // are never overwritten, so calling it twice (e.g., on resume) is safe.
142
+ applyStylesheet(graph, config.inheritedStylesheet);
143
+ const checkpointManager = new CheckpointManager();
144
+ // Checkpoint is always written to this path (filename is fixed by convention)
145
+ const checkpointFilePath = path.join(config.logsRoot, 'checkpoint.json');
146
+ // ConvergenceController for goal gate evaluation (story 42-16)
147
+ const controller = createConvergenceController();
148
+ // Convergence budget and plateau managers (story 45-8)
149
+ const sessionManager = new SessionBudgetManager();
150
+ const pipelineManager = new PipelineBudgetManager();
151
+ const plateauDetector = createPlateauDetector({
152
+ ...(config.plateauWindow !== undefined ? { window: config.plateauWindow } : {}),
153
+ ...(config.plateauThreshold !== undefined ? { threshold: config.plateauThreshold } : {}),
154
+ });
155
+ let convergenceIteration = 0;
156
+ // Persistence state (story 46-3)
157
+ const runStartedAt = new Date().toISOString();
158
+ // Tracks which node is currently executing — used by scenario:completed handler
159
+ // to populate node_id in scenario_results rows (event payload has no nodeId field).
160
+ let lastScenarioNodeId = '';
161
+ // Helper: persist a run exit (success or failure) when adapter is present.
162
+ // Called at every `return` path that terminates the run.
163
+ // Persistence errors must not crash the executor — log as warnings.
164
+ const persistExit = async (finalStatus, finalOutcome) => {
165
+ if (!config.adapter)
166
+ return;
167
+ try {
168
+ await upsertGraphRun(config.adapter, {
169
+ id: config.runId,
170
+ graph_file: graph.id || config.runId,
171
+ ...(graph.goal ? { graph_goal: graph.goal } : {}),
172
+ status: finalStatus,
173
+ started_at: runStartedAt,
174
+ completed_at: new Date().toISOString(),
175
+ final_outcome: finalOutcome,
176
+ total_cost_usd: pipelineManager.getTotalCost(),
177
+ node_count: graph.nodes.size,
178
+ });
179
+ }
180
+ catch (persistErr) {
181
+ const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
182
+ console.warn(`[executor] graph_runs upsert failed for run ${config.runId}: ${msg}`);
183
+ }
184
+ };
185
+ // Execution state
186
+ let completedNodes = [];
187
+ let nodeRetries = {};
188
+ let context = new GraphContext(config.initialContext);
189
+ let step = 0;
190
+ // Cycle detection: counts how many times each node is visited
191
+ const visitCount = new Map();
192
+ // Tracks FAIL-outcome conditional edge routing count per node (bounds review loops)
193
+ const failRouteCount = new Map();
194
+ // Resume state (non-null when config.checkpointPath is set)
195
+ let resumeCompletedSet = null;
196
+ // Fidelity override for the first resumed node ('summary:high' or '')
197
+ let firstResumedFidelity = '';
198
+ // loopRestart flags: suppress cycle check / completed push for intentional loops
199
+ let skipCycleCheck = false;
200
+ let skipCompletedPush = false;
201
+ // Tracks the edge that led to the current node (for fidelity resolution). Story 49-5.
202
+ let lastIncomingEdge = undefined;
203
+ // Capture scenario manifest for integrity checks (story 44-4).
204
+ // Only runs when scenarioStore is configured; otherwise skipped (backward-compatible).
205
+ let scenarioManifest = null;
206
+ if (config.scenarioStore) {
207
+ scenarioManifest = await config.scenarioStore.discover();
208
+ }
209
+ // RunStateManager for per-run artifact persistence (story 44-7).
210
+ // Opt-in: only instantiated when dotSource is provided. Backward-compatible.
211
+ const runStateManager = config.dotSource
212
+ ? new RunStateManager({ runDir: config.logsRoot })
213
+ : null;
214
+ if (runStateManager) {
215
+ await runStateManager.initRun(config.dotSource);
216
+ }
217
+ // -----------------------------------------------------------------------
218
+ // Persistence: subscribe to scenario:completed for score tracking (story 46-3)
219
+ // The event payload does not include nodeId, so we use lastScenarioNodeId
220
+ // which is set to currentNode.id each time a node starts executing.
221
+ // -----------------------------------------------------------------------
222
+ if (config.adapter && config.eventBus) {
223
+ const persistAdapter = config.adapter;
224
+ const scenarioHandler = (payload) => {
225
+ const threshold = config.satisfactionThreshold ?? 0.8;
226
+ const scored = computeSatisfactionScore(payload.results, threshold);
227
+ insertScenarioResult(persistAdapter, {
228
+ run_id: config.runId,
229
+ node_id: lastScenarioNodeId || 'unknown',
230
+ iteration: payload.iteration,
231
+ total_scenarios: payload.results.summary.total,
232
+ passed: payload.results.summary.passed,
233
+ failed: payload.results.summary.failed,
234
+ satisfaction_score: scored.score,
235
+ threshold: scored.threshold,
236
+ passes: scored.passes,
237
+ details: JSON.stringify(scored.breakdown),
238
+ executed_at: new Date().toISOString(),
239
+ }).catch((err) => {
240
+ // Persistence errors must not crash the executor — log at debug level only
241
+ const msg = err instanceof Error ? err.message : String(err);
242
+ console.warn(`[executor] scenario_results persistence failed for run ${config.runId}: ${msg}`);
243
+ });
244
+ };
245
+ config.eventBus.on('scenario:completed', scenarioHandler);
246
+ }
247
+ // -----------------------------------------------------------------------
248
+ // Persistence: insert graph_runs row at run start (story 46-3)
249
+ // Persistence errors must not crash the executor — swallow silently.
250
+ // -----------------------------------------------------------------------
251
+ if (config.adapter) {
252
+ try {
253
+ await upsertGraphRun(config.adapter, {
254
+ id: config.runId,
255
+ graph_file: graph.id || config.runId,
256
+ ...(graph.goal ? { graph_goal: graph.goal } : {}),
257
+ status: 'running',
258
+ started_at: runStartedAt,
259
+ node_count: graph.nodes.size,
260
+ });
261
+ }
262
+ catch (persistErr) {
263
+ const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
264
+ console.warn(`[executor] graph_runs insert failed for run ${config.runId}: ${msg}`);
265
+ }
266
+ }
267
+ // -----------------------------------------------------------------------
268
+ // Determine starting node (normal start or resume)
269
+ // -----------------------------------------------------------------------
270
+ let currentNode;
271
+ if (config.checkpointPath) {
272
+ const checkpoint = await checkpointManager.load(config.checkpointPath);
273
+ const resumeState = checkpointManager.resume(graph, checkpoint);
274
+ context = resumeState.context;
275
+ completedNodes = [...resumeState.completedNodes];
276
+ nodeRetries = { ...resumeState.nodeRetries };
277
+ firstResumedFidelity = resumeState.firstResumedNodeFidelity;
278
+ resumeCompletedSet = resumeState.completedNodes;
279
+ if (resumeState.completedNodes.has(checkpoint.currentNode)) {
280
+ // Last checkpoint node was fully completed — resume from the NEXT node
281
+ const lastNode = graph.nodes.get(checkpoint.currentNode);
282
+ if (lastNode) {
283
+ // KNOWN LIMITATION: The Checkpoint type does not store the final outcome
284
+ // status of the last completed node, so we must assume SUCCESS when calling
285
+ // selectEdge() to advance past it during resume. If the checkpointed node's
286
+ // actual last outcome was non-SUCCESS (e.g., FAILURE with a dedicated failure
287
+ // edge), resume will select the SUCCESS edge rather than the FAILURE edge,
288
+ // diverging from the original execution path. Storing `lastOutcomeStatus` in
289
+ // the Checkpoint type would allow a faithful replay.
290
+ const nextEdge = await selectEdge(lastNode, { status: 'SUCCESS' }, context, graph, {
291
+ ...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
292
+ runId: config.runId,
293
+ });
294
+ if (nextEdge) {
295
+ const nextNode = graph.nodes.get(nextEdge.toNode);
296
+ if (!nextNode) {
297
+ throw new Error(`Edge target node "${nextEdge.toNode}" not found in graph`);
298
+ }
299
+ currentNode = nextNode;
300
+ }
301
+ else {
302
+ // No outgoing edge from last completed node — may already be done
303
+ currentNode = graph.startNode();
304
+ }
305
+ }
306
+ else {
307
+ currentNode = graph.startNode();
308
+ }
309
+ }
310
+ else {
311
+ // Last checkpoint node was NOT completed (process was interrupted mid-node)
312
+ // Re-dispatch it from the resumed run
313
+ const resumeNode = graph.nodes.get(checkpoint.currentNode);
314
+ if (resumeNode) {
315
+ currentNode = resumeNode;
316
+ }
317
+ else {
318
+ currentNode = graph.startNode();
319
+ }
320
+ }
321
+ }
322
+ else {
323
+ currentNode = graph.startNode();
324
+ }
325
+ // -----------------------------------------------------------------------
326
+ // Write runId to context so handlers can read it via context.getString("__runId")
327
+ // Set here (after all context assignments) so it covers both fresh-start and resume.
328
+ // Story 50-9 (AC4).
329
+ // -----------------------------------------------------------------------
330
+ context.set('__runId', config.runId ?? 'unknown');
331
+ // -----------------------------------------------------------------------
332
+ // Main traversal loop
333
+ // -----------------------------------------------------------------------
334
+ while (true) {
335
+ // --- Budget checks (story 45-8): session budget (highest priority), then pipeline ---
336
+ // Budget enforcement priority order: session > pipeline > per-node retries (dispatchWithRetry)
337
+ const sessionResult = sessionManager.checkBudget((config.wallClockCapMs ?? 0) / 1000);
338
+ if (!sessionResult.allowed) {
339
+ config.eventBus?.emit('convergence:budget-exhausted', {
340
+ runId: config.runId,
341
+ level: 'session',
342
+ reason: sessionResult.reason,
343
+ });
344
+ await persistExit('failed', `Session budget exceeded: ${sessionResult.reason}`);
345
+ return { status: 'FAIL', failureReason: `Session budget exceeded: ${sessionResult.reason}` };
346
+ }
347
+ const pipelineResult = pipelineManager.checkBudget(config.pipelineBudgetCapUsd ?? 0);
348
+ if (!pipelineResult.allowed) {
349
+ config.eventBus?.emit('convergence:budget-exhausted', {
350
+ runId: config.runId,
351
+ level: 'pipeline',
352
+ reason: pipelineResult.reason,
353
+ });
354
+ await persistExit('failed', `Pipeline budget exceeded: ${pipelineResult.reason}`);
355
+ return { status: 'FAIL', failureReason: `Pipeline budget exceeded: ${pipelineResult.reason}` };
356
+ }
357
+ // Exit condition: arrived at the exit node → evaluate goal gates (story 42-16)
358
+ const exitNode = graph.exitNode();
359
+ if (currentNode.id === exitNode.id) {
360
+ // scenario-primary mode forces satisfaction score as the authoritative gate signal (story 46-6)
361
+ const useScenarioPrimary = config.qualityMode === 'scenario-primary';
362
+ const gateResult = controller.checkGoalGates(graph, config.runId, config.eventBus, (useScenarioPrimary || config.satisfactionThreshold !== undefined)
363
+ ? { context, satisfactionThreshold: config.satisfactionThreshold ?? 0.8 }
364
+ : undefined);
365
+ // Emit scenario:advisory-computed when code review verdict is in context and mode is scenario-primary (story 46-6)
366
+ if (useScenarioPrimary && config.eventBus) {
367
+ const rawVerdict = context.getString(CONTEXT_KEY_CODE_REVIEW_VERDICT, '');
368
+ if (rawVerdict !== '') {
369
+ const codeReviewVerdict = rawVerdict;
370
+ const coordinator = createDualSignalCoordinator({
371
+ eventBus: config.eventBus,
372
+ threshold: config.satisfactionThreshold ?? 0.8,
373
+ qualityMode: 'scenario-primary',
374
+ });
375
+ const score = context.getNumber('satisfaction_score', 0);
376
+ coordinator.evaluate(codeReviewVerdict, score, config.runId);
377
+ }
378
+ }
379
+ if (!gateResult.satisfied) {
380
+ // Use ConvergenceController.resolveRetryTarget (story 45-8 — replaces inline 4-step chain)
381
+ const failingNodeId = gateResult.failedGates[0];
382
+ const failingGateNode = graph.nodes.get(failingNodeId);
383
+ const retryTargetId = failingGateNode
384
+ ? controller.resolveRetryTarget(failingGateNode, graph)
385
+ : null;
386
+ if (!retryTargetId) {
387
+ await persistExit('failed', 'Goal gate failed: no retry target');
388
+ return { status: 'FAIL', failureReason: 'Goal gate failed: no retry target' };
389
+ }
390
+ const retryNode = graph.nodes.get(retryTargetId);
391
+ if (!retryNode) {
392
+ throw new Error(`Retry target node "${retryTargetId}" not found in graph`);
393
+ }
394
+ // Increment convergence iteration and record satisfaction score for plateau detection
395
+ convergenceIteration++;
396
+ const satisfactionScore = context.getNumber('satisfaction_score', 0.0);
397
+ plateauDetector.recordScore(convergenceIteration, satisfactionScore);
398
+ // Check for plateau (story 45-8, AC5)
399
+ const plateauResult = checkPlateauAndEmit(plateauDetector, {
400
+ runId: config.runId,
401
+ nodeId: retryTargetId,
402
+ ...(config.eventBus ? { eventBus: config.eventBus } : {}),
403
+ });
404
+ if (plateauResult.plateaued) {
405
+ await persistExit('failed', `Convergence plateau detected after ${convergenceIteration} iteration(s)`);
406
+ return {
407
+ status: 'FAIL',
408
+ failureReason: `Convergence plateau detected after ${convergenceIteration} iteration(s): scores plateaued at [${plateauResult.scores.join(', ')}]`,
409
+ };
410
+ }
411
+ // Build and inject remediation context before routing to retry target (story 45-8, AC6)
412
+ const remediation = buildRemediationContext({
413
+ previousFailureReason: `Goal gate unsatisfied: ${gateResult.failedGates.join(', ')}`,
414
+ iterationCount: convergenceIteration,
415
+ satisfactionScoreHistory: plateauResult.scores,
416
+ });
417
+ injectRemediationContext(context, remediation);
418
+ // Compress old iteration contexts if auto-summarizer threshold
419
+ // exceeded (story 49-3). This prevents unbounded token growth in
420
+ // long convergence loops by summarizing earlier iterations.
421
+ await controller.prepareForIteration(convergenceIteration);
422
+ // Route to retry target; suppress cycle check for convergence loop retry
423
+ skipCycleCheck = true;
424
+ currentNode = retryNode;
425
+ continue;
426
+ }
427
+ await persistExit('completed', 'SUCCESS');
428
+ return { status: 'SUCCESS' };
429
+ }
430
+ // Resume skip: nodes already completed in a prior run are advanced over
431
+ // without dispatching their handler again
432
+ if (resumeCompletedSet?.has(currentNode.id)) {
433
+ // Cast to GraphOutcome (types.ts:Outcome) as required by selectEdge API.
434
+ const skipEdge = await selectEdge(currentNode, { status: 'SUCCESS' }, context, graph, {
435
+ ...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
436
+ runId: config.runId,
437
+ });
438
+ if (!skipEdge) {
439
+ await persistExit('failed', `No outgoing edge from node ${currentNode.id}`);
440
+ return {
441
+ status: 'FAIL',
442
+ failureReason: `No outgoing edge from node ${currentNode.id}`,
443
+ };
444
+ }
445
+ config.eventBus?.emit('graph:edge-selected', {
446
+ runId: config.runId,
447
+ fromNode: currentNode.id,
448
+ toNode: skipEdge.toNode,
449
+ step,
450
+ ...(skipEdge.label !== '' ? { edgeLabel: skipEdge.label } : {}),
451
+ });
452
+ step++;
453
+ const skipNextNode = graph.nodes.get(skipEdge.toNode);
454
+ if (!skipNextNode) {
455
+ throw new Error(`Edge target node "${skipEdge.toNode}" not found in graph`);
456
+ }
457
+ currentNode = skipNextNode;
458
+ continue;
459
+ }
460
+ // Cycle detection — exempt for nodes reached via loopRestart edges
461
+ if (!skipCycleCheck) {
462
+ const count = (visitCount.get(currentNode.id) ?? 0) + 1;
463
+ visitCount.set(currentNode.id, count);
464
+ if (count > graph.nodes.size * 3) {
465
+ throw new Error(`Graph cycle detected: node ${currentNode.id} visited ${count} times`);
466
+ }
467
+ }
468
+ skipCycleCheck = false;
469
+ // Integrity check: verify scenario files before dispatching any tool node (story 44-4)
470
+ if (currentNode.type === 'tool' && config.scenarioStore && scenarioManifest) {
471
+ const integrityResult = await config.scenarioStore.verifyIntegrity(scenarioManifest);
472
+ if (!integrityResult.valid) {
473
+ config.eventBus?.emit('scenario:integrity-failed', {
474
+ runId: config.runId,
475
+ nodeId: currentNode.id,
476
+ tampered: integrityResult.tampered,
477
+ });
478
+ await persistExit('failed', `Scenario integrity violation before node "${currentNode.id}"`);
479
+ return {
480
+ status: 'FAIL',
481
+ failureReason: `Scenario integrity violation detected before node "${currentNode.id}": tampered files: ${integrityResult.tampered.join(', ')}`,
482
+ };
483
+ }
484
+ config.eventBus?.emit('scenario:integrity-passed', {
485
+ runId: config.runId,
486
+ nodeId: currentNode.id,
487
+ scenarioCount: scenarioManifest.scenarios.length,
488
+ });
489
+ }
490
+ // ----------------------------------------------------------------
491
+ // Track current node ID for scenario:completed event handler (story 46-3)
492
+ // The scenario:completed event payload has no nodeId field, so we capture it here.
493
+ // ----------------------------------------------------------------
494
+ lastScenarioNodeId = currentNode.id;
495
+ // ----------------------------------------------------------------
496
+ // Emit graph:node-started before handler invocation
497
+ // ----------------------------------------------------------------
498
+ config.eventBus?.emit('graph:node-started', {
499
+ runId: config.runId,
500
+ nodeId: currentNode.id,
501
+ nodeType: currentNode.type,
502
+ });
503
+ // ----------------------------------------------------------------
504
+ // Fidelity override for the first resumed node
505
+ // ----------------------------------------------------------------
506
+ const nodeToDispatch = firstResumedFidelity !== ''
507
+ ? { ...currentNode, fidelity: firstResumedFidelity }
508
+ : currentNode;
509
+ firstResumedFidelity = ''; // clear after first use
510
+ // ----------------------------------------------------------------
511
+ // Pre-dispatch context summarization based on node fidelity (story 49-5)
512
+ // ----------------------------------------------------------------
513
+ if (config.summaryEngine) {
514
+ const effectiveFidelity = resolveFidelity(nodeToDispatch, lastIncomingEdge, graph);
515
+ const summaryLevel = parseFidelityLevel(effectiveFidelity);
516
+ if (summaryLevel !== null) {
517
+ const nodeContextContent = context.getString('factory.nodeContext', '');
518
+ if (nodeContextContent !== '') {
519
+ const summary = await config.summaryEngine.summarize(nodeContextContent, summaryLevel);
520
+ context.set('factory.compressedNodeContext', summary.content);
521
+ // Replace the primary context so downstream handlers use the
522
+ // compressed version. The original is preserved in
523
+ // factory.compressedNodeContext.originalHash for cache expansion.
524
+ context.set('factory.nodeContext', summary.content);
525
+ config.eventBus?.emit('graph:context-summarized', {
526
+ runId: config.runId,
527
+ nodeId: nodeToDispatch.id,
528
+ level: summaryLevel,
529
+ originalTokenCount: summary.originalTokenCount ?? 0,
530
+ summaryTokenCount: summary.summaryTokenCount ?? 0,
531
+ });
532
+ }
533
+ }
534
+ }
535
+ // Record dispatch start time for artifact timing (story 44-7)
536
+ const startedAt = Date.now();
537
+ // ----------------------------------------------------------------
538
+ // Dispatch handler with retry logic
539
+ // ----------------------------------------------------------------
540
+ let outcome = await dispatchWithRetry(nodeToDispatch, context, graph, config, nodeRetries);
541
+ // ----------------------------------------------------------------
542
+ // Hot-spin guard: if the handler completed in under 50ms (e.g., default
543
+ // handler returning instantly), yield the event loop to prevent CPU
544
+ // saturation in convergence loops with no-op handlers. In real pipelines
545
+ // handlers take minutes, so this never fires.
546
+ // ----------------------------------------------------------------
547
+ if (Date.now() - startedAt < 50) {
548
+ await new Promise((r) => setTimeout(r, 50));
549
+ }
550
+ // ----------------------------------------------------------------
551
+ // allowPartial demotion (story 42-16, AC2/AC3)
552
+ // After the retry loop exits and the final outcome is determined:
553
+ // if the node does not accept PARTIAL_SUCCESS, demote to FAIL.
554
+ // This check uses nodeToDispatch (which has the correct allowPartial value).
555
+ // ----------------------------------------------------------------
556
+ if (outcome.status === 'PARTIAL_SUCCESS' && !nodeToDispatch.allowPartial) {
557
+ outcome = {
558
+ ...outcome,
559
+ status: 'FAIL',
560
+ failureReason: outcome.failureReason
561
+ ? `${outcome.failureReason} (PARTIAL_SUCCESS not accepted: allowPartial=false)`
562
+ : 'PARTIAL_SUCCESS not accepted: allowPartial=false',
563
+ };
564
+ }
565
+ // ----------------------------------------------------------------
566
+ // Write per-node artifacts (story 44-7)
567
+ // Called after allowPartial demotion so the persisted status reflects the final outcome.
568
+ // ----------------------------------------------------------------
569
+ if (runStateManager) {
570
+ const completedAt = Date.now();
571
+ const nodeArtifacts = {
572
+ nodeId: nodeToDispatch.id,
573
+ nodeType: nodeToDispatch.type,
574
+ status: outcome.status,
575
+ startedAt,
576
+ completedAt,
577
+ durationMs: completedAt - startedAt,
578
+ };
579
+ if (nodeToDispatch.type === 'codergen') {
580
+ const rawPrompt = nodeToDispatch.prompt || nodeToDispatch.label;
581
+ if (rawPrompt)
582
+ nodeArtifacts.prompt = rawPrompt;
583
+ if (typeof outcome.notes === 'string')
584
+ nodeArtifacts.response = outcome.notes;
585
+ }
586
+ await runStateManager.writeNodeArtifacts(nodeArtifacts);
587
+ }
588
+ // ----------------------------------------------------------------
589
+ // Emit node completion/failure event AFTER allowPartial demotion (story 42-16)
590
+ // This placement ensures graph:node-failed is emitted when PARTIAL_SUCCESS is
591
+ // demoted to FAIL, and graph:node-completed is never emitted for a demoted node.
592
+ // ----------------------------------------------------------------
593
+ if (outcome.status === 'FAIL') {
594
+ config.eventBus?.emit('graph:node-failed', {
595
+ runId: config.runId,
596
+ nodeId: nodeToDispatch.id,
597
+ failureReason: outcome.failureReason ?? 'Unknown failure',
598
+ });
599
+ }
600
+ else {
601
+ config.eventBus?.emit('graph:node-completed', {
602
+ runId: config.runId,
603
+ nodeId: nodeToDispatch.id,
604
+ outcome,
605
+ });
606
+ }
607
+ // ----------------------------------------------------------------
608
+ // Record outcome with ConvergenceController (story 42-16)
609
+ // Map events.ts StageStatus to types.ts OutcomeStatus for the controller.
610
+ // ----------------------------------------------------------------
611
+ {
612
+ const controllerStatus = outcome.status === 'SUCCESS' ? 'SUCCESS'
613
+ : outcome.status === 'PARTIAL_SUCCESS' ? 'PARTIAL_SUCCESS'
614
+ : 'FAILURE';
615
+ controller.recordOutcome(nodeToDispatch.id, controllerStatus);
616
+ // Record iteration context for auto-summarization (story 49-3).
617
+ // The context string captures the outcome so compression can
618
+ // preserve key facts from earlier iterations.
619
+ const iterContent = context.getString('factory.nodeContext', '');
620
+ controller.recordIterationContext({
621
+ index: convergenceIteration,
622
+ content: iterContent,
623
+ });
624
+ }
625
+ // ----------------------------------------------------------------
626
+ // Apply context updates from outcome
627
+ // ----------------------------------------------------------------
628
+ if (outcome.contextUpdates) {
629
+ for (const [key, value] of Object.entries(outcome.contextUpdates)) {
630
+ context.set(key, value);
631
+ }
632
+ }
633
+ // Set 'outcome' in context so conditional edges (e.g. condition="outcome=success")
634
+ // can reference the handler's result. Status is lowercased for consistency with
635
+ // DOT convention (outcome=success, outcome=fail).
636
+ // NOTE: This overwrites on every node. For sequential graphs this is correct — each
637
+ // node's outcome is available to its outgoing edge conditions. For future parallel
638
+ // subgraphs (Epic 50), this would need to be scoped per-subgraph to avoid clobbering.
639
+ context.set('outcome', outcome.status.toLowerCase());
640
+ // ----------------------------------------------------------------
641
+ // Accumulate per-node cost for pipeline budget tracking (story 45-8)
642
+ // Convention: CodergenBackend writes 'factory.lastNodeCostUsd' to contextUpdates.
643
+ // The key holds only the LAST node's cost; PipelineBudgetManager owns the running total.
644
+ // This must run AFTER contextUpdates are applied so context.getNumber reflects latest output.
645
+ // ----------------------------------------------------------------
646
+ const nodeCost = context.getNumber('factory.lastNodeCostUsd', 0);
647
+ if (nodeCost > 0) {
648
+ pipelineManager.addCost(nodeCost);
649
+ }
650
+ // ----------------------------------------------------------------
651
+ // Persistence: write per-node result row (story 46-3, AC4)
652
+ // Written after allowPartial demotion (outcome.status is final here)
653
+ // and after cost accumulation so cost_usd reflects the actual node cost.
654
+ // ----------------------------------------------------------------
655
+ if (config.adapter) {
656
+ const nodeCompletedAt = Date.now();
657
+ try {
658
+ await insertGraphNodeResult(config.adapter, {
659
+ run_id: config.runId,
660
+ node_id: nodeToDispatch.id,
661
+ attempt: (nodeRetries[nodeToDispatch.id] ?? 0) + 1,
662
+ status: outcome.status,
663
+ started_at: new Date(startedAt).toISOString(),
664
+ completed_at: new Date(nodeCompletedAt).toISOString(),
665
+ duration_ms: nodeCompletedAt - startedAt,
666
+ cost_usd: nodeCost,
667
+ ...(outcome.failureReason !== undefined ? { failure_reason: outcome.failureReason } : {}),
668
+ });
669
+ }
670
+ catch (persistErr) {
671
+ const msg = persistErr instanceof Error ? persistErr.message : String(persistErr);
672
+ console.warn(`[executor] graph_node_results insert failed for node ${currentNode.id}: ${msg}`);
673
+ }
674
+ }
675
+ // ----------------------------------------------------------------
676
+ // Push completed node (skip for loopRestart re-entry nodes)
677
+ // ----------------------------------------------------------------
678
+ if (!skipCompletedPush) {
679
+ completedNodes.push(currentNode.id);
680
+ }
681
+ skipCompletedPush = false;
682
+ // ----------------------------------------------------------------
683
+ // Save checkpoint after each node completion
684
+ // ----------------------------------------------------------------
685
+ await checkpointManager.save(config.logsRoot, {
686
+ currentNode: currentNode.id,
687
+ completedNodes,
688
+ nodeRetries,
689
+ context,
690
+ });
691
+ config.eventBus?.emit('graph:checkpoint-saved', {
692
+ runId: config.runId,
693
+ nodeId: currentNode.id,
694
+ checkpointPath: checkpointFilePath,
695
+ });
696
+ // ----------------------------------------------------------------
697
+ // FAIL routing (story 42-16)
698
+ // When outcome is FAIL (including demoted PARTIAL_SUCCESS), route to
699
+ // the node-level retryTarget chain or return FAIL immediately.
700
+ // ----------------------------------------------------------------
701
+ if (outcome.status === 'FAIL') {
702
+ // Resolves via 4-level chain: node.retryTarget → node.fallbackRetryTarget → graph.retryTarget → graph.fallbackRetryTarget → null (story 45-2)
703
+ const retryTarget = controller.resolveRetryTarget(currentNode, graph);
704
+ if (retryTarget) {
705
+ const retryNode = graph.nodes.get(retryTarget);
706
+ if (!retryNode) {
707
+ throw new Error(`Retry target node "${retryTarget}" not found in graph`);
708
+ }
709
+ skipCycleCheck = true;
710
+ currentNode = retryNode;
711
+ continue;
712
+ }
713
+ // No retry target found. If this node has conditional outgoing edges
714
+ // (e.g. code_review with shape=diamond), fall through to edge selection so
715
+ // condition-based routing can handle the FAIL outcome. Otherwise return FAIL.
716
+ const outgoing = graph.edges.filter((e) => e.fromNode === currentNode.id);
717
+ const hasConditionalEdge = outgoing.some((e) => e.condition && e.condition.trim() !== '');
718
+ if (!hasConditionalEdge) {
719
+ await persistExit('failed', outcome.failureReason ?? 'FAIL');
720
+ return {
721
+ status: 'FAIL',
722
+ ...(outcome.failureReason !== undefined && { failureReason: outcome.failureReason }),
723
+ };
724
+ }
725
+ // Fall through to edge selection for conditional routing.
726
+ // The cycle detection (visitCount) bounds this loop — conditional edge targets
727
+ // with maxRetries>0 (e.g. dev_story set by --max-review-cycles) will eventually
728
+ // hit the visit limit. Additionally, track fail-route count as a safeguard.
729
+ const routeCount = (failRouteCount.get(currentNode.id) ?? 0) + 1;
730
+ failRouteCount.set(currentNode.id, routeCount);
731
+ // Safeguard: cap fail-route loops at graph.defaultMaxRetries or 3 (whichever is higher)
732
+ if (routeCount > Math.max(graph.defaultMaxRetries || 0, 3)) {
733
+ await persistExit('failed', outcome.failureReason ?? 'FAIL');
734
+ return {
735
+ status: 'FAIL',
736
+ ...(outcome.failureReason !== undefined && { failureReason: outcome.failureReason }),
737
+ };
738
+ }
739
+ }
740
+ // ----------------------------------------------------------------
741
+ // Select next edge
742
+ // ----------------------------------------------------------------
743
+ // Cast outcome to GraphOutcome (types.ts:Outcome) as required by selectEdge API.
744
+ const edge = await selectEdge(currentNode, outcome, context, graph, {
745
+ ...(config.eventBus !== undefined ? { eventBus: config.eventBus } : {}),
746
+ runId: config.runId,
747
+ });
748
+ if (!edge) {
749
+ await persistExit('failed', `No outgoing edge from node ${currentNode.id}`);
750
+ return {
751
+ status: 'FAIL',
752
+ failureReason: `No outgoing edge from node ${currentNode.id}`,
753
+ };
754
+ }
755
+ // ----------------------------------------------------------------
756
+ // Emit graph:edge-selected after edge selection
757
+ // ----------------------------------------------------------------
758
+ config.eventBus?.emit('graph:edge-selected', {
759
+ runId: config.runId,
760
+ fromNode: currentNode.id,
761
+ toNode: edge.toNode,
762
+ step,
763
+ ...(edge.label !== '' ? { edgeLabel: edge.label } : {}),
764
+ });
765
+ step++;
766
+ // ----------------------------------------------------------------
767
+ // Handle loopRestart: next iteration skips cycle check and
768
+ // completed push (treating target as a fresh re-entry)
769
+ // ----------------------------------------------------------------
770
+ if (edge.loopRestart) {
771
+ skipCycleCheck = true;
772
+ skipCompletedPush = true;
773
+ }
774
+ // ----------------------------------------------------------------
775
+ // Advance to next node
776
+ // ----------------------------------------------------------------
777
+ const nextNode = graph.nodes.get(edge.toNode);
778
+ if (!nextNode) {
779
+ throw new Error(`Edge target node "${edge.toNode}" not found in graph`);
780
+ }
781
+ lastIncomingEdge = edge;
782
+ currentNode = nextNode;
783
+ }
784
+ },
785
+ };
786
+ }
787
+ //# sourceMappingURL=executor.js.map