smol-symphony 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (716) hide show
  1. package/AGENTS.md +41 -22
  2. package/DESIGN.md +494 -273
  3. package/README.md +109 -57
  4. package/SPEC.md +33 -24
  5. package/WORKFLOW.minimal.yaml +34 -0
  6. package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
  7. package/WORKFLOW.yaml +487 -0
  8. package/assets/skills/symphony-issues/SKILL.md +136 -0
  9. package/assets/symphony-mise.system.toml +68 -0
  10. package/dist/src/bin/symphony.js +30 -0
  11. package/dist/src/bin/symphony.js.map +1 -0
  12. package/dist/src/core/actions/context.js +109 -0
  13. package/dist/src/core/actions/context.js.map +1 -0
  14. package/dist/{actions/parsing.js → src/core/actions/parse.js} +33 -114
  15. package/dist/src/core/actions/parse.js.map +1 -0
  16. package/dist/src/core/actions/plan.js +197 -0
  17. package/dist/src/core/actions/plan.js.map +1 -0
  18. package/dist/src/core/actions/predicates.js +111 -0
  19. package/dist/src/core/actions/predicates.js.map +1 -0
  20. package/dist/src/core/actions/run-fold.js +248 -0
  21. package/dist/src/core/actions/run-fold.js.map +1 -0
  22. package/dist/src/core/actions/template.js +118 -0
  23. package/dist/src/core/actions/template.js.map +1 -0
  24. package/dist/src/core/cli/args.js +116 -0
  25. package/dist/src/core/cli/args.js.map +1 -0
  26. package/dist/src/core/coerce.js +75 -0
  27. package/dist/src/core/coerce.js.map +1 -0
  28. package/dist/src/core/credential/account-id.js +20 -0
  29. package/dist/src/core/credential/account-id.js.map +1 -0
  30. package/dist/src/core/credential/adapter-config.js +136 -0
  31. package/dist/src/core/credential/adapter-config.js.map +1 -0
  32. package/dist/src/core/credential/availability.js +98 -0
  33. package/dist/src/core/credential/availability.js.map +1 -0
  34. package/dist/src/core/credential/extract.js +228 -0
  35. package/dist/src/core/credential/extract.js.map +1 -0
  36. package/dist/src/core/credential/fake-creds.js +171 -0
  37. package/dist/src/core/credential/fake-creds.js.map +1 -0
  38. package/dist/src/core/credential/identity.js +125 -0
  39. package/dist/src/core/credential/identity.js.map +1 -0
  40. package/dist/src/core/credential/shape.js +230 -0
  41. package/dist/src/core/credential/shape.js.map +1 -0
  42. package/dist/src/core/credential/strings.js +15 -0
  43. package/dist/src/core/credential/strings.js.map +1 -0
  44. package/dist/src/core/doctor/checks.js +303 -0
  45. package/dist/src/core/doctor/checks.js.map +1 -0
  46. package/dist/src/core/git/result.js +107 -0
  47. package/dist/src/core/git/result.js.map +1 -0
  48. package/dist/src/core/http/decisions.js +225 -0
  49. package/dist/src/core/http/decisions.js.map +1 -0
  50. package/dist/{http.js → src/core/http/render.js} +472 -738
  51. package/dist/src/core/http/render.js.map +1 -0
  52. package/dist/{http-handlers.js → src/core/http/routes.js} +52 -87
  53. package/dist/src/core/http/routes.js.map +1 -0
  54. package/dist/src/core/http/views.js +181 -0
  55. package/dist/src/core/http/views.js.map +1 -0
  56. package/dist/src/core/image/managed-image.js +95 -0
  57. package/dist/src/core/image/managed-image.js.map +1 -0
  58. package/dist/src/core/issue/file.js +149 -0
  59. package/dist/src/core/issue/file.js.map +1 -0
  60. package/dist/src/core/issue/parse.js +210 -0
  61. package/dist/src/core/issue/parse.js.map +1 -0
  62. package/dist/src/core/mcp/dispatch.js +239 -0
  63. package/dist/src/core/mcp/dispatch.js.map +1 -0
  64. package/dist/src/core/mcp/post-move.js +92 -0
  65. package/dist/src/core/mcp/post-move.js.map +1 -0
  66. package/dist/src/core/mcp/protocol.js +293 -0
  67. package/dist/src/core/mcp/protocol.js.map +1 -0
  68. package/dist/src/core/mcp/url.js +162 -0
  69. package/dist/src/core/mcp/url.js.map +1 -0
  70. package/dist/src/core/path.js +63 -0
  71. package/dist/src/core/path.js.map +1 -0
  72. package/dist/src/core/reconcile/image-decide.js +48 -0
  73. package/dist/src/core/reconcile/image-decide.js.map +1 -0
  74. package/dist/src/core/reconcile/ledger.js +142 -0
  75. package/dist/src/core/reconcile/ledger.js.map +1 -0
  76. package/dist/src/core/reconcile/pr-classify.js +62 -0
  77. package/dist/src/core/reconcile/pr-classify.js.map +1 -0
  78. package/dist/{reconciler → src/core/reconcile}/pr-decide.js +25 -12
  79. package/dist/src/core/reconcile/pr-decide.js.map +1 -0
  80. package/dist/src/core/reconcile/pr-loop.js +161 -0
  81. package/dist/src/core/reconcile/pr-loop.js.map +1 -0
  82. package/dist/src/core/reconcile/pr-notes.js +35 -0
  83. package/dist/src/core/reconcile/pr-notes.js.map +1 -0
  84. package/dist/src/core/reconcile/vm-decide.js +70 -0
  85. package/dist/src/core/reconcile/vm-decide.js.map +1 -0
  86. package/dist/src/core/reconcile/vm-reap.js +207 -0
  87. package/dist/src/core/reconcile/vm-reap.js.map +1 -0
  88. package/dist/src/core/reconcile/workspace-decide.js +162 -0
  89. package/dist/src/core/reconcile/workspace-decide.js.map +1 -0
  90. package/dist/src/core/runlog/summary.js +231 -0
  91. package/dist/src/core/runlog/summary.js.map +1 -0
  92. package/dist/src/core/runner/dispatch-config.js +95 -0
  93. package/dist/src/core/runner/dispatch-config.js.map +1 -0
  94. package/dist/src/core/runner/injection.js +61 -0
  95. package/dist/src/core/runner/injection.js.map +1 -0
  96. package/dist/src/core/runner/mise.js +210 -0
  97. package/dist/src/core/runner/mise.js.map +1 -0
  98. package/dist/src/core/runner/prompt.js +720 -0
  99. package/dist/src/core/runner/prompt.js.map +1 -0
  100. package/dist/src/core/runner/turn.js +242 -0
  101. package/dist/src/core/runner/turn.js.map +1 -0
  102. package/dist/src/core/runner/vm-plan.js +390 -0
  103. package/dist/src/core/runner/vm-plan.js.map +1 -0
  104. package/dist/src/core/schedule/admission.js +123 -0
  105. package/dist/src/core/schedule/admission.js.map +1 -0
  106. package/dist/src/core/schedule/circuit-breaker.js +111 -0
  107. package/dist/src/core/schedule/circuit-breaker.js.map +1 -0
  108. package/dist/src/core/schedule/eligibility.js +83 -0
  109. package/dist/src/core/schedule/eligibility.js.map +1 -0
  110. package/dist/src/core/schedule/reconcile-issue.js +82 -0
  111. package/dist/src/core/schedule/reconcile-issue.js.map +1 -0
  112. package/dist/src/core/schedule/retry.js +96 -0
  113. package/dist/src/core/schedule/retry.js.map +1 -0
  114. package/dist/src/core/schedule/sleep-cycle.js +133 -0
  115. package/dist/src/core/schedule/sleep-cycle.js.map +1 -0
  116. package/dist/src/core/schedule/slots.js +124 -0
  117. package/dist/src/core/schedule/slots.js.map +1 -0
  118. package/dist/src/core/schedule/tick.js +553 -0
  119. package/dist/src/core/schedule/tick.js.map +1 -0
  120. package/dist/src/core/schedule/token-fold.js +181 -0
  121. package/dist/src/core/schedule/token-fold.js.map +1 -0
  122. package/dist/src/core/state-resolve.js +86 -0
  123. package/dist/src/core/state-resolve.js.map +1 -0
  124. package/dist/src/core/vm-guards.js +278 -0
  125. package/dist/src/core/vm-guards.js.map +1 -0
  126. package/dist/src/core/workflow/derive.js +107 -0
  127. package/dist/src/core/workflow/derive.js.map +1 -0
  128. package/dist/src/core/workflow/parse.js +687 -0
  129. package/dist/src/core/workflow/parse.js.map +1 -0
  130. package/dist/src/core/workflow/prompt-probe.js +78 -0
  131. package/dist/src/core/workflow/prompt-probe.js.map +1 -0
  132. package/dist/src/core/workflow/validate.js +189 -0
  133. package/dist/src/core/workflow/validate.js.map +1 -0
  134. package/dist/src/core/workspace-key.js +19 -0
  135. package/dist/src/core/workspace-key.js.map +1 -0
  136. package/dist/src/shell/actions-runner.js +356 -0
  137. package/dist/src/shell/actions-runner.js.map +1 -0
  138. package/dist/src/shell/adapter/adapter-registry.js +45 -0
  139. package/dist/src/shell/adapter/adapter-registry.js.map +1 -0
  140. package/dist/src/shell/adapter/clock-random.js +96 -0
  141. package/dist/src/shell/adapter/clock-random.js.map +1 -0
  142. package/dist/src/shell/adapter/gondolin-dispatch-helpers.js +158 -0
  143. package/dist/src/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
  144. package/dist/src/shell/adapter/gondolin-dispatch.js +385 -0
  145. package/dist/src/shell/adapter/gondolin-dispatch.js.map +1 -0
  146. package/dist/src/shell/adapter/gondolin-image-converter.js +233 -0
  147. package/dist/src/shell/adapter/gondolin-image-converter.js.map +1 -0
  148. package/dist/src/shell/adapter/gondolin-image-fetch.js +180 -0
  149. package/dist/src/shell/adapter/gondolin-image-fetch.js.map +1 -0
  150. package/dist/src/shell/adapter/launcher-asset.js +57 -0
  151. package/dist/src/shell/adapter/launcher-asset.js.map +1 -0
  152. package/dist/src/shell/adapter/mise-config-asset.js +65 -0
  153. package/dist/src/shell/adapter/mise-config-asset.js.map +1 -0
  154. package/dist/src/shell/adapter/workflow-loader.js +304 -0
  155. package/dist/src/shell/adapter/workflow-loader.js.map +1 -0
  156. package/dist/src/shell/cli/doctor.js +268 -0
  157. package/dist/src/shell/cli/doctor.js.map +1 -0
  158. package/dist/src/shell/effect-interpreter-families.js +314 -0
  159. package/dist/src/shell/effect-interpreter-families.js.map +1 -0
  160. package/dist/src/shell/effect-interpreter.js +29 -0
  161. package/dist/src/shell/effect-interpreter.js.map +1 -0
  162. package/dist/src/shell/interp/acp-frame.js +137 -0
  163. package/dist/src/shell/interp/acp-frame.js.map +1 -0
  164. package/dist/src/shell/interp/acp-ws-conn.js +320 -0
  165. package/dist/src/shell/interp/acp-ws-conn.js.map +1 -0
  166. package/dist/src/shell/interp/acp-ws-frames.js +159 -0
  167. package/dist/src/shell/interp/acp-ws-frames.js.map +1 -0
  168. package/dist/src/shell/interp/acp-ws.js +197 -0
  169. package/dist/src/shell/interp/acp-ws.js.map +1 -0
  170. package/dist/src/shell/interp/acp.js +319 -0
  171. package/dist/src/shell/interp/acp.js.map +1 -0
  172. package/dist/src/shell/interp/credential-defaults.js +128 -0
  173. package/dist/src/shell/interp/credential-defaults.js.map +1 -0
  174. package/dist/src/shell/interp/credential-hooks.js +149 -0
  175. package/dist/src/shell/interp/credential-hooks.js.map +1 -0
  176. package/dist/src/shell/interp/credential-registry.js +226 -0
  177. package/dist/src/shell/interp/credential-registry.js.map +1 -0
  178. package/dist/src/shell/interp/credential.js +103 -0
  179. package/dist/src/shell/interp/credential.js.map +1 -0
  180. package/dist/src/shell/interp/gh.js +163 -0
  181. package/dist/src/shell/interp/gh.js.map +1 -0
  182. package/dist/src/shell/interp/git.js +28 -0
  183. package/dist/src/shell/interp/git.js.map +1 -0
  184. package/dist/src/shell/interp/log.js +213 -0
  185. package/dist/src/shell/interp/log.js.map +1 -0
  186. package/dist/src/shell/interp/process.js +178 -0
  187. package/dist/src/shell/interp/process.js.map +1 -0
  188. package/dist/src/shell/interp/runlog.js +193 -0
  189. package/dist/src/shell/interp/runlog.js.map +1 -0
  190. package/dist/src/shell/interp/timer.js +64 -0
  191. package/dist/src/shell/interp/timer.js.map +1 -0
  192. package/dist/src/shell/interp/tracker-disk.js +99 -0
  193. package/dist/src/shell/interp/tracker-disk.js.map +1 -0
  194. package/dist/src/shell/interp/tracker-parse.js +71 -0
  195. package/dist/src/shell/interp/tracker-parse.js.map +1 -0
  196. package/dist/src/shell/interp/tracker-scan.js +238 -0
  197. package/dist/src/shell/interp/tracker-scan.js.map +1 -0
  198. package/dist/src/shell/interp/tracker-write.js +91 -0
  199. package/dist/src/shell/interp/tracker-write.js.map +1 -0
  200. package/dist/src/shell/interp/tracker.js +41 -0
  201. package/dist/src/shell/interp/tracker.js.map +1 -0
  202. package/dist/src/shell/interp/tty.js +48 -0
  203. package/dist/src/shell/interp/tty.js.map +1 -0
  204. package/dist/src/shell/interp/vm.js +199 -0
  205. package/dist/src/shell/interp/vm.js.map +1 -0
  206. package/dist/src/shell/interp/workspace.js +310 -0
  207. package/dist/src/shell/interp/workspace.js.map +1 -0
  208. package/dist/src/shell/main-acp.js +78 -0
  209. package/dist/src/shell/main-acp.js.map +1 -0
  210. package/dist/src/shell/main-adapters.js +222 -0
  211. package/dist/src/shell/main-adapters.js.map +1 -0
  212. package/dist/src/shell/main-credential.js +122 -0
  213. package/dist/src/shell/main-credential.js.map +1 -0
  214. package/dist/src/shell/main-doctor.js +22 -0
  215. package/dist/src/shell/main-doctor.js.map +1 -0
  216. package/dist/src/shell/main-entry.js +46 -0
  217. package/dist/src/shell/main-entry.js.map +1 -0
  218. package/dist/src/shell/main-http-csrf.js +45 -0
  219. package/dist/src/shell/main-http-csrf.js.map +1 -0
  220. package/dist/src/shell/main-http-handler.js +389 -0
  221. package/dist/src/shell/main-http-handler.js.map +1 -0
  222. package/dist/src/shell/main-http-mcp.js +122 -0
  223. package/dist/src/shell/main-http-mcp.js.map +1 -0
  224. package/dist/src/shell/main-http-views.js +253 -0
  225. package/dist/src/shell/main-http-views.js.map +1 -0
  226. package/dist/src/shell/main-http.js +76 -0
  227. package/dist/src/shell/main-http.js.map +1 -0
  228. package/dist/src/shell/main-loops.js +130 -0
  229. package/dist/src/shell/main-loops.js.map +1 -0
  230. package/dist/src/shell/main-mcp.js +129 -0
  231. package/dist/src/shell/main-mcp.js.map +1 -0
  232. package/dist/src/shell/main-orchestrator.js +120 -0
  233. package/dist/src/shell/main-orchestrator.js.map +1 -0
  234. package/dist/src/shell/main-preflight.js +43 -0
  235. package/dist/src/shell/main-preflight.js.map +1 -0
  236. package/dist/src/shell/main-reconcilers-helpers.js +244 -0
  237. package/dist/src/shell/main-reconcilers-helpers.js.map +1 -0
  238. package/dist/src/shell/main-reconcilers-pr.js +148 -0
  239. package/dist/src/shell/main-reconcilers-pr.js.map +1 -0
  240. package/dist/src/shell/main-reconcilers.js +225 -0
  241. package/dist/src/shell/main-reconcilers.js.map +1 -0
  242. package/dist/src/shell/main-runner.js +355 -0
  243. package/dist/src/shell/main-runner.js.map +1 -0
  244. package/dist/src/shell/main-scaffold.js +116 -0
  245. package/dist/src/shell/main-scaffold.js.map +1 -0
  246. package/dist/src/shell/main-shutdown.js +115 -0
  247. package/dist/src/shell/main-shutdown.js.map +1 -0
  248. package/dist/src/shell/main-startup.js +48 -0
  249. package/dist/src/shell/main-startup.js.map +1 -0
  250. package/dist/src/shell/main-substrates.js +43 -0
  251. package/dist/src/shell/main-substrates.js.map +1 -0
  252. package/dist/src/shell/main.js +385 -0
  253. package/dist/src/shell/main.js.map +1 -0
  254. package/dist/src/shell/orchestrator-feedback.js +69 -0
  255. package/dist/src/shell/orchestrator-feedback.js.map +1 -0
  256. package/dist/src/shell/orchestrator-image.js +167 -0
  257. package/dist/src/shell/orchestrator-image.js.map +1 -0
  258. package/dist/src/shell/orchestrator-loop.js +468 -0
  259. package/dist/src/shell/orchestrator-loop.js.map +1 -0
  260. package/dist/src/shell/orchestrator-reconcile.js +36 -0
  261. package/dist/src/shell/orchestrator-reconcile.js.map +1 -0
  262. package/dist/src/shell/reconciler-loop.js +228 -0
  263. package/dist/src/shell/reconciler-loop.js.map +1 -0
  264. package/dist/src/shell/runner-loop-turn.js +301 -0
  265. package/dist/src/shell/runner-loop-turn.js.map +1 -0
  266. package/dist/src/shell/runner-loop.js +338 -0
  267. package/dist/src/shell/runner-loop.js.map +1 -0
  268. package/dist/src/shell/server/http.js +208 -0
  269. package/dist/src/shell/server/http.js.map +1 -0
  270. package/dist/src/shell/server/mcp-runtime-effects.js +237 -0
  271. package/dist/src/shell/server/mcp-runtime-effects.js.map +1 -0
  272. package/dist/src/shell/server/mcp-runtime.js +99 -0
  273. package/dist/src/shell/server/mcp-runtime.js.map +1 -0
  274. package/dist/src/shell/workspace-key.js +14 -0
  275. package/dist/src/shell/workspace-key.js.map +1 -0
  276. package/dist/src/types/acp.js +8 -0
  277. package/dist/src/types/acp.js.map +1 -0
  278. package/dist/src/types/actions/plan.js +6 -0
  279. package/dist/src/types/actions/plan.js.map +1 -0
  280. package/dist/src/types/actions/predicates.js +6 -0
  281. package/dist/src/types/actions/predicates.js.map +1 -0
  282. package/dist/src/types/actions/run-fold.js +8 -0
  283. package/dist/src/types/actions/run-fold.js.map +1 -0
  284. package/dist/src/types/actions.js +7 -0
  285. package/dist/src/types/actions.js.map +1 -0
  286. package/dist/src/types/adapter/clock-random.js +4 -0
  287. package/dist/src/types/adapter/clock-random.js.map +1 -0
  288. package/dist/src/types/adapter/gondolin-image-converter.js +5 -0
  289. package/dist/src/types/adapter/gondolin-image-converter.js.map +1 -0
  290. package/dist/src/types/adapter/gondolin-image-fetch.js +5 -0
  291. package/dist/src/types/adapter/gondolin-image-fetch.js.map +1 -0
  292. package/dist/src/types/adapter/workflow-loader.js +4 -0
  293. package/dist/src/types/adapter/workflow-loader.js.map +1 -0
  294. package/dist/src/types/cli/args.js +8 -0
  295. package/dist/src/types/cli/args.js.map +1 -0
  296. package/dist/src/types/config.js +8 -0
  297. package/dist/src/types/config.js.map +1 -0
  298. package/dist/src/types/credential-interp.js +6 -0
  299. package/dist/src/types/credential-interp.js.map +1 -0
  300. package/dist/src/types/credentials.js +10 -0
  301. package/dist/src/types/credentials.js.map +1 -0
  302. package/dist/src/types/doctor.js +7 -0
  303. package/dist/src/types/doctor.js.map +1 -0
  304. package/dist/src/types/domain.js +7 -0
  305. package/dist/src/types/domain.js.map +1 -0
  306. package/dist/src/types/effect.js +15 -0
  307. package/dist/src/types/effect.js.map +1 -0
  308. package/dist/src/types/errors.js +39 -0
  309. package/dist/src/types/errors.js.map +1 -0
  310. package/dist/src/types/http/decisions.js +6 -0
  311. package/dist/src/types/http/decisions.js.map +1 -0
  312. package/dist/src/types/http/render.js +10 -0
  313. package/dist/src/types/http/render.js.map +1 -0
  314. package/dist/src/types/http/views.js +6 -0
  315. package/dist/src/types/http/views.js.map +1 -0
  316. package/dist/src/types/http.js +9 -0
  317. package/dist/src/types/http.js.map +1 -0
  318. package/dist/src/types/image/managed-image.js +7 -0
  319. package/dist/src/types/image/managed-image.js.map +1 -0
  320. package/dist/src/types/interp/effect-interpreter.js +8 -0
  321. package/dist/src/types/interp/effect-interpreter.js.map +1 -0
  322. package/dist/src/types/interp/tracker.js +7 -0
  323. package/dist/src/types/interp/tracker.js.map +1 -0
  324. package/dist/src/types/issue/file.js +6 -0
  325. package/dist/src/types/issue/file.js.map +1 -0
  326. package/dist/src/types/issue/parse.js +8 -0
  327. package/dist/src/types/issue/parse.js.map +1 -0
  328. package/dist/src/types/main-acp.js +13 -0
  329. package/dist/src/types/main-acp.js.map +1 -0
  330. package/dist/src/types/main-adapters.js +5 -0
  331. package/dist/src/types/main-adapters.js.map +1 -0
  332. package/dist/src/types/main-credential.js +21 -0
  333. package/dist/src/types/main-credential.js.map +1 -0
  334. package/dist/src/types/main-doctor.js +6 -0
  335. package/dist/src/types/main-doctor.js.map +1 -0
  336. package/dist/src/types/main-http-handler.js +12 -0
  337. package/dist/src/types/main-http-handler.js.map +1 -0
  338. package/dist/src/types/main-http.js +5 -0
  339. package/dist/src/types/main-http.js.map +1 -0
  340. package/dist/src/types/main-loops.js +5 -0
  341. package/dist/src/types/main-loops.js.map +1 -0
  342. package/dist/src/types/main-mcp.js +12 -0
  343. package/dist/src/types/main-mcp.js.map +1 -0
  344. package/dist/src/types/main-orchestrator.js +5 -0
  345. package/dist/src/types/main-orchestrator.js.map +1 -0
  346. package/dist/src/types/main-reconcilers.js +11 -0
  347. package/dist/src/types/main-reconcilers.js.map +1 -0
  348. package/dist/src/types/main-runner.js +13 -0
  349. package/dist/src/types/main-runner.js.map +1 -0
  350. package/dist/src/types/main-startup.js +5 -0
  351. package/dist/src/types/main-startup.js.map +1 -0
  352. package/dist/src/types/main-substrates.js +5 -0
  353. package/dist/src/types/main-substrates.js.map +1 -0
  354. package/dist/src/types/mcp/dispatch.js +4 -0
  355. package/dist/src/types/mcp/dispatch.js.map +1 -0
  356. package/dist/src/types/mcp/post-move.js +7 -0
  357. package/dist/src/types/mcp/post-move.js.map +1 -0
  358. package/dist/src/types/mcp.js +9 -0
  359. package/dist/src/types/mcp.js.map +1 -0
  360. package/dist/src/types/ports.js +12 -0
  361. package/dist/src/types/ports.js.map +1 -0
  362. package/dist/src/types/reconcile/image-decide.js +5 -0
  363. package/dist/src/types/reconcile/image-decide.js.map +1 -0
  364. package/dist/src/types/reconcile/ledger.js +7 -0
  365. package/dist/src/types/reconcile/ledger.js.map +1 -0
  366. package/dist/src/types/reconcile/pr-loop.js +8 -0
  367. package/dist/src/types/reconcile/pr-loop.js.map +1 -0
  368. package/dist/src/types/reconcile/vm-reap.js +8 -0
  369. package/dist/src/types/reconcile/vm-reap.js.map +1 -0
  370. package/dist/src/types/reconcile/workspace-decide.js +7 -0
  371. package/dist/src/types/reconcile/workspace-decide.js.map +1 -0
  372. package/dist/src/types/reconcile.js +9 -0
  373. package/dist/src/types/reconcile.js.map +1 -0
  374. package/dist/src/types/runlog.js +7 -0
  375. package/dist/src/types/runlog.js.map +1 -0
  376. package/dist/src/types/runner/actions-runner.js +12 -0
  377. package/dist/src/types/runner/actions-runner.js.map +1 -0
  378. package/dist/src/types/runner/gondolin-dispatch.js +5 -0
  379. package/dist/src/types/runner/gondolin-dispatch.js.map +1 -0
  380. package/dist/src/types/runner/injection.js +6 -0
  381. package/dist/src/types/runner/injection.js.map +1 -0
  382. package/dist/src/types/runner/runner-loop.js +5 -0
  383. package/dist/src/types/runner/runner-loop.js.map +1 -0
  384. package/dist/src/types/runner/turn.js +4 -0
  385. package/dist/src/types/runner/turn.js.map +1 -0
  386. package/dist/src/types/runner/vm-plan.js +4 -0
  387. package/dist/src/types/runner/vm-plan.js.map +1 -0
  388. package/dist/src/types/runtime.js +9 -0
  389. package/dist/src/types/runtime.js.map +1 -0
  390. package/dist/src/types/schedule/admission.js +7 -0
  391. package/dist/src/types/schedule/admission.js.map +1 -0
  392. package/dist/src/types/schedule/circuit-breaker.js +2 -0
  393. package/dist/src/types/schedule/circuit-breaker.js.map +1 -0
  394. package/dist/src/types/schedule/eligibility.js +9 -0
  395. package/dist/src/types/schedule/eligibility.js.map +1 -0
  396. package/dist/src/types/schedule/orchestrator-loop.js +10 -0
  397. package/dist/src/types/schedule/orchestrator-loop.js.map +1 -0
  398. package/dist/src/types/schedule/sleep-cycle.js +4 -0
  399. package/dist/src/types/schedule/sleep-cycle.js.map +1 -0
  400. package/dist/src/types/schedule/slots.js +8 -0
  401. package/dist/src/types/schedule/slots.js.map +1 -0
  402. package/dist/src/types/schedule/tick.js +9 -0
  403. package/dist/src/types/schedule/tick.js.map +1 -0
  404. package/dist/src/types/server/mcp-runtime.js +8 -0
  405. package/dist/src/types/server/mcp-runtime.js.map +1 -0
  406. package/dist/src/types/workflow/parse.js +4 -0
  407. package/dist/src/types/workflow/parse.js.map +1 -0
  408. package/dist/tests/core/account-id.test.js +35 -0
  409. package/dist/tests/core/account-id.test.js.map +1 -0
  410. package/dist/tests/core/actions-parse.test.js +176 -0
  411. package/dist/tests/core/actions-parse.test.js.map +1 -0
  412. package/dist/tests/core/adapter-config.test.js +133 -0
  413. package/dist/tests/core/adapter-config.test.js.map +1 -0
  414. package/dist/tests/core/admission.test.js +215 -0
  415. package/dist/tests/core/admission.test.js.map +1 -0
  416. package/dist/tests/core/args.test.js +132 -0
  417. package/dist/tests/core/args.test.js.map +1 -0
  418. package/dist/tests/core/availability.test.js +62 -0
  419. package/dist/tests/core/availability.test.js.map +1 -0
  420. package/dist/tests/core/checks.test.js +395 -0
  421. package/dist/tests/core/checks.test.js.map +1 -0
  422. package/dist/tests/core/circuit-breaker.test.js +172 -0
  423. package/dist/tests/core/circuit-breaker.test.js.map +1 -0
  424. package/dist/tests/core/coerce.test.js +87 -0
  425. package/dist/tests/core/coerce.test.js.map +1 -0
  426. package/dist/tests/core/context.test.js +228 -0
  427. package/dist/tests/core/context.test.js.map +1 -0
  428. package/dist/tests/core/decisions.test.js +310 -0
  429. package/dist/tests/core/decisions.test.js.map +1 -0
  430. package/dist/tests/core/derive.test.js +205 -0
  431. package/dist/tests/core/derive.test.js.map +1 -0
  432. package/dist/tests/core/dispatch-config.test.js +164 -0
  433. package/dist/tests/core/dispatch-config.test.js.map +1 -0
  434. package/dist/tests/core/dispatch.test.js +302 -0
  435. package/dist/tests/core/dispatch.test.js.map +1 -0
  436. package/dist/tests/core/eligibility.test.js +163 -0
  437. package/dist/tests/core/eligibility.test.js.map +1 -0
  438. package/dist/tests/core/extract.test.js +139 -0
  439. package/dist/tests/core/extract.test.js.map +1 -0
  440. package/dist/tests/core/fake-creds.test.js +134 -0
  441. package/dist/tests/core/fake-creds.test.js.map +1 -0
  442. package/dist/tests/core/file.test.js +197 -0
  443. package/dist/tests/core/file.test.js.map +1 -0
  444. package/dist/tests/core/git-result.test.js +113 -0
  445. package/dist/tests/core/git-result.test.js.map +1 -0
  446. package/dist/tests/core/identity.test.js +180 -0
  447. package/dist/tests/core/identity.test.js.map +1 -0
  448. package/dist/tests/core/image-decide.test.js +59 -0
  449. package/dist/tests/core/image-decide.test.js.map +1 -0
  450. package/dist/tests/core/injection.test.js +163 -0
  451. package/dist/tests/core/injection.test.js.map +1 -0
  452. package/dist/tests/core/ledger.test.js +218 -0
  453. package/dist/tests/core/ledger.test.js.map +1 -0
  454. package/dist/tests/core/managed-image.test.js +68 -0
  455. package/dist/tests/core/managed-image.test.js.map +1 -0
  456. package/dist/tests/core/mise.test.js +138 -0
  457. package/dist/tests/core/mise.test.js.map +1 -0
  458. package/dist/tests/core/parse.test.js +174 -0
  459. package/dist/tests/core/parse.test.js.map +1 -0
  460. package/dist/tests/core/path.test.js +50 -0
  461. package/dist/tests/core/path.test.js.map +1 -0
  462. package/dist/tests/core/plan.test.js +218 -0
  463. package/dist/tests/core/plan.test.js.map +1 -0
  464. package/dist/tests/core/post-move.test.js +162 -0
  465. package/dist/tests/core/post-move.test.js.map +1 -0
  466. package/dist/tests/core/pr-classify.test.js +117 -0
  467. package/dist/tests/core/pr-classify.test.js.map +1 -0
  468. package/dist/tests/core/pr-decide.test.js +298 -0
  469. package/dist/tests/core/pr-decide.test.js.map +1 -0
  470. package/dist/tests/core/pr-loop.test.js +301 -0
  471. package/dist/tests/core/pr-loop.test.js.map +1 -0
  472. package/dist/tests/core/pr-notes.test.js +165 -0
  473. package/dist/tests/core/pr-notes.test.js.map +1 -0
  474. package/dist/tests/core/predicates.test.js +154 -0
  475. package/dist/tests/core/predicates.test.js.map +1 -0
  476. package/dist/tests/core/prompt.test.js +189 -0
  477. package/dist/tests/core/prompt.test.js.map +1 -0
  478. package/dist/tests/core/protocol.test.js +195 -0
  479. package/dist/tests/core/protocol.test.js.map +1 -0
  480. package/dist/tests/core/reconcile-issue.test.js +116 -0
  481. package/dist/tests/core/reconcile-issue.test.js.map +1 -0
  482. package/dist/tests/core/render.test.js +549 -0
  483. package/dist/tests/core/render.test.js.map +1 -0
  484. package/dist/tests/core/retry.test.js +186 -0
  485. package/dist/tests/core/retry.test.js.map +1 -0
  486. package/dist/tests/core/routes.test.js +247 -0
  487. package/dist/tests/core/routes.test.js.map +1 -0
  488. package/dist/tests/core/run-fold.test.js +299 -0
  489. package/dist/tests/core/run-fold.test.js.map +1 -0
  490. package/dist/tests/core/shape.test.js +185 -0
  491. package/dist/tests/core/shape.test.js.map +1 -0
  492. package/dist/tests/core/sleep-cycle.test.js +150 -0
  493. package/dist/tests/core/sleep-cycle.test.js.map +1 -0
  494. package/dist/tests/core/slots.test.js +201 -0
  495. package/dist/tests/core/slots.test.js.map +1 -0
  496. package/dist/tests/core/state-resolve.test.js +80 -0
  497. package/dist/tests/core/state-resolve.test.js.map +1 -0
  498. package/dist/tests/core/summary.test.js +200 -0
  499. package/dist/tests/core/summary.test.js.map +1 -0
  500. package/dist/tests/core/template.test.js +116 -0
  501. package/dist/tests/core/template.test.js.map +1 -0
  502. package/dist/tests/core/tick.test.js +558 -0
  503. package/dist/tests/core/tick.test.js.map +1 -0
  504. package/dist/tests/core/token-fold.test.js +176 -0
  505. package/dist/tests/core/token-fold.test.js.map +1 -0
  506. package/dist/tests/core/turn.test.js +388 -0
  507. package/dist/tests/core/turn.test.js.map +1 -0
  508. package/dist/tests/core/url.test.js +118 -0
  509. package/dist/tests/core/url.test.js.map +1 -0
  510. package/dist/tests/core/validate.test.js +247 -0
  511. package/dist/tests/core/validate.test.js.map +1 -0
  512. package/dist/tests/core/views.test.js +252 -0
  513. package/dist/tests/core/views.test.js.map +1 -0
  514. package/dist/tests/core/vm-decide.test.js +110 -0
  515. package/dist/tests/core/vm-decide.test.js.map +1 -0
  516. package/dist/tests/core/vm-guards.test.js +153 -0
  517. package/dist/tests/core/vm-guards.test.js.map +1 -0
  518. package/dist/tests/core/vm-plan.test.js +332 -0
  519. package/dist/tests/core/vm-plan.test.js.map +1 -0
  520. package/dist/tests/core/vm-reap.test.js +196 -0
  521. package/dist/tests/core/vm-reap.test.js.map +1 -0
  522. package/dist/tests/core/workflow-parse.test.js +493 -0
  523. package/dist/tests/core/workflow-parse.test.js.map +1 -0
  524. package/dist/tests/core/workspace-decide.test.js +236 -0
  525. package/dist/tests/core/workspace-decide.test.js.map +1 -0
  526. package/dist/tests/helpers/fixtures.js +167 -0
  527. package/dist/tests/helpers/fixtures.js.map +1 -0
  528. package/dist/tests/shell/acp-substrate.test.js +101 -0
  529. package/dist/tests/shell/acp-substrate.test.js.map +1 -0
  530. package/dist/tests/shell/actions-runner-push.test.js +203 -0
  531. package/dist/tests/shell/actions-runner-push.test.js.map +1 -0
  532. package/dist/tests/shell/credential-hooks.test.js +36 -0
  533. package/dist/tests/shell/credential-hooks.test.js.map +1 -0
  534. package/dist/tests/shell/credential-registry.test.js +165 -0
  535. package/dist/tests/shell/credential-registry.test.js.map +1 -0
  536. package/dist/tests/shell/credential-substrate.test.js +179 -0
  537. package/dist/tests/shell/credential-substrate.test.js.map +1 -0
  538. package/dist/tests/shell/dockerfile-mise-pin.test.js +51 -0
  539. package/dist/tests/shell/dockerfile-mise-pin.test.js.map +1 -0
  540. package/dist/tests/shell/doctor.test.js +101 -0
  541. package/dist/tests/shell/doctor.test.js.map +1 -0
  542. package/dist/tests/shell/effect-vm-create.test.js +52 -0
  543. package/dist/tests/shell/effect-vm-create.test.js.map +1 -0
  544. package/dist/tests/shell/gh-port.test.js +63 -0
  545. package/dist/tests/shell/gh-port.test.js.map +1 -0
  546. package/dist/tests/shell/gondolin-dispatch-guard.test.js +144 -0
  547. package/dist/tests/shell/gondolin-dispatch-guard.test.js.map +1 -0
  548. package/dist/tests/shell/gondolin-dispatch-shquote.test.js +168 -0
  549. package/dist/tests/shell/gondolin-dispatch-shquote.test.js.map +1 -0
  550. package/dist/tests/shell/gondolin-image-converter.test.js +208 -0
  551. package/dist/tests/shell/gondolin-image-converter.test.js.map +1 -0
  552. package/dist/tests/shell/gondolin-image-fetch.test.js +93 -0
  553. package/dist/tests/shell/gondolin-image-fetch.test.js.map +1 -0
  554. package/dist/tests/shell/http-handler.test.js +608 -0
  555. package/dist/tests/shell/http-handler.test.js.map +1 -0
  556. package/dist/tests/shell/http-server.test.js +53 -0
  557. package/dist/tests/shell/http-server.test.js.map +1 -0
  558. package/dist/tests/shell/mcp-runtime.test.js +366 -0
  559. package/dist/tests/shell/mcp-runtime.test.js.map +1 -0
  560. package/dist/tests/shell/mise-config-asset.test.js +87 -0
  561. package/dist/tests/shell/mise-config-asset.test.js.map +1 -0
  562. package/dist/tests/shell/orchestrator-loop.test.js +583 -0
  563. package/dist/tests/shell/orchestrator-loop.test.js.map +1 -0
  564. package/dist/tests/shell/reconciler-passes.test.js +314 -0
  565. package/dist/tests/shell/reconciler-passes.test.js.map +1 -0
  566. package/dist/tests/shell/runner-loop-turn.test.js +97 -0
  567. package/dist/tests/shell/runner-loop-turn.test.js.map +1 -0
  568. package/dist/tests/shell/runner-slice.test.js +536 -0
  569. package/dist/tests/shell/runner-slice.test.js.map +1 -0
  570. package/dist/tests/shell/scaffold.test.js +65 -0
  571. package/dist/tests/shell/scaffold.test.js.map +1 -0
  572. package/dist/tests/shell/tick-config.test.js +83 -0
  573. package/dist/tests/shell/tick-config.test.js.map +1 -0
  574. package/dist/tests/shell/tracker-parse-dates.test.js +44 -0
  575. package/dist/tests/shell/tracker-parse-dates.test.js.map +1 -0
  576. package/dist/tests/shell/tracker-write-issue.test.js +154 -0
  577. package/dist/tests/shell/tracker-write-issue.test.js.map +1 -0
  578. package/dist/tests/shell/workflow-prompt-split.test.js +208 -0
  579. package/dist/tests/shell/workflow-prompt-split.test.js.map +1 -0
  580. package/dist/tests/shell/workspace-live-config.test.js +140 -0
  581. package/dist/tests/shell/workspace-live-config.test.js.map +1 -0
  582. package/package.json +21 -9
  583. package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
  584. package/prompts/Reflect.md +91 -0
  585. package/prompts/Review.md +97 -0
  586. package/prompts/Todo.md +96 -0
  587. package/prompts/_footer.md +41 -0
  588. package/prompts/_preamble.md +42 -0
  589. package/prompts-minimal/Todo.md +26 -0
  590. package/scripts/postinstall.mjs +63 -0
  591. package/scripts/vm-agent.mjs +312 -90
  592. package/WORKFLOW.md +0 -744
  593. package/dist/acp-bridge.js +0 -324
  594. package/dist/acp-bridge.js.map +0 -1
  595. package/dist/actions/cache.js +0 -191
  596. package/dist/actions/cache.js.map +0 -1
  597. package/dist/actions/effects.js +0 -41
  598. package/dist/actions/effects.js.map +0 -1
  599. package/dist/actions/executor.js +0 -570
  600. package/dist/actions/executor.js.map +0 -1
  601. package/dist/actions/index.js +0 -13
  602. package/dist/actions/index.js.map +0 -1
  603. package/dist/actions/parsing.js.map +0 -1
  604. package/dist/actions/predicate-env.js +0 -27
  605. package/dist/actions/predicate-env.js.map +0 -1
  606. package/dist/actions/predicates.js +0 -49
  607. package/dist/actions/predicates.js.map +0 -1
  608. package/dist/actions/templating.js +0 -66
  609. package/dist/actions/templating.js.map +0 -1
  610. package/dist/actions/types.js +0 -15
  611. package/dist/actions/types.js.map +0 -1
  612. package/dist/agent/acp.js +0 -473
  613. package/dist/agent/acp.js.map +0 -1
  614. package/dist/agent/adapter-names.js +0 -159
  615. package/dist/agent/adapter-names.js.map +0 -1
  616. package/dist/agent/adapters.js +0 -511
  617. package/dist/agent/adapters.js.map +0 -1
  618. package/dist/agent/credential-extractors.js +0 -342
  619. package/dist/agent/credential-extractors.js.map +0 -1
  620. package/dist/agent/credential-secrets.js +0 -628
  621. package/dist/agent/credential-secrets.js.map +0 -1
  622. package/dist/agent/credential-ticker.js +0 -57
  623. package/dist/agent/credential-ticker.js.map +0 -1
  624. package/dist/agent/gondolin-creds-staging.js +0 -356
  625. package/dist/agent/gondolin-creds-staging.js.map +0 -1
  626. package/dist/agent/gondolin-dispatch.js +0 -375
  627. package/dist/agent/gondolin-dispatch.js.map +0 -1
  628. package/dist/agent/gondolin.js +0 -124
  629. package/dist/agent/gondolin.js.map +0 -1
  630. package/dist/agent/runner-decisions.js +0 -134
  631. package/dist/agent/runner-decisions.js.map +0 -1
  632. package/dist/agent/runner.js +0 -1456
  633. package/dist/agent/runner.js.map +0 -1
  634. package/dist/agent/tool-call-summary.js +0 -102
  635. package/dist/agent/tool-call-summary.js.map +0 -1
  636. package/dist/agent/vm-acp-mapping.js +0 -73
  637. package/dist/agent/vm-acp-mapping.js.map +0 -1
  638. package/dist/agent/vm-guards.js +0 -262
  639. package/dist/agent/vm-guards.js.map +0 -1
  640. package/dist/agent/vm-port.js +0 -22
  641. package/dist/agent/vm-port.js.map +0 -1
  642. package/dist/agent/vm-process-registry.js +0 -79
  643. package/dist/agent/vm-process-registry.js.map +0 -1
  644. package/dist/bin/cli-args.js +0 -105
  645. package/dist/bin/cli-args.js.map +0 -1
  646. package/dist/bin/symphony.js +0 -794
  647. package/dist/bin/symphony.js.map +0 -1
  648. package/dist/errors.js +0 -15
  649. package/dist/errors.js.map +0 -1
  650. package/dist/http-disk.js +0 -135
  651. package/dist/http-disk.js.map +0 -1
  652. package/dist/http-handlers.js.map +0 -1
  653. package/dist/http.js.map +0 -1
  654. package/dist/issues.js +0 -178
  655. package/dist/issues.js.map +0 -1
  656. package/dist/logging.js +0 -203
  657. package/dist/logging.js.map +0 -1
  658. package/dist/mcp.js +0 -706
  659. package/dist/mcp.js.map +0 -1
  660. package/dist/memory.js +0 -85
  661. package/dist/memory.js.map +0 -1
  662. package/dist/orchestrator-decisions.js +0 -331
  663. package/dist/orchestrator-decisions.js.map +0 -1
  664. package/dist/orchestrator.js +0 -1569
  665. package/dist/orchestrator.js.map +0 -1
  666. package/dist/prompt.js +0 -65
  667. package/dist/prompt.js.map +0 -1
  668. package/dist/reconciler/cache.js +0 -65
  669. package/dist/reconciler/cache.js.map +0 -1
  670. package/dist/reconciler/index.js +0 -448
  671. package/dist/reconciler/index.js.map +0 -1
  672. package/dist/reconciler/ledger.js +0 -131
  673. package/dist/reconciler/ledger.js.map +0 -1
  674. package/dist/reconciler/pr-adapters.js +0 -174
  675. package/dist/reconciler/pr-adapters.js.map +0 -1
  676. package/dist/reconciler/pr-decide.js.map +0 -1
  677. package/dist/reconciler/pr.js +0 -422
  678. package/dist/reconciler/pr.js.map +0 -1
  679. package/dist/reconciler/types.js +0 -12
  680. package/dist/reconciler/types.js.map +0 -1
  681. package/dist/reconciler/vm.js +0 -243
  682. package/dist/reconciler/vm.js.map +0 -1
  683. package/dist/reconciler/workspace-defaults.js +0 -83
  684. package/dist/reconciler/workspace-defaults.js.map +0 -1
  685. package/dist/reconciler/workspace.js +0 -272
  686. package/dist/reconciler/workspace.js.map +0 -1
  687. package/dist/runlog.js +0 -403
  688. package/dist/runlog.js.map +0 -1
  689. package/dist/scaffold.js +0 -165
  690. package/dist/scaffold.js.map +0 -1
  691. package/dist/trackers/local.js +0 -445
  692. package/dist/trackers/local.js.map +0 -1
  693. package/dist/trackers/types.js +0 -10
  694. package/dist/trackers/types.js.map +0 -1
  695. package/dist/types.js +0 -3
  696. package/dist/types.js.map +0 -1
  697. package/dist/util/clock.js +0 -12
  698. package/dist/util/clock.js.map +0 -1
  699. package/dist/util/crypto.js +0 -25
  700. package/dist/util/crypto.js.map +0 -1
  701. package/dist/util/frontmatter.js +0 -70
  702. package/dist/util/frontmatter.js.map +0 -1
  703. package/dist/util/fs-issues.js +0 -22
  704. package/dist/util/fs-issues.js.map +0 -1
  705. package/dist/util/process.js +0 -152
  706. package/dist/util/process.js.map +0 -1
  707. package/dist/util/workspace-key.js +0 -10
  708. package/dist/util/workspace-key.js.map +0 -1
  709. package/dist/workflow-loader.js +0 -147
  710. package/dist/workflow-loader.js.map +0 -1
  711. package/dist/workflow.js +0 -822
  712. package/dist/workflow.js.map +0 -1
  713. package/dist/workspace-types.js +0 -8
  714. package/dist/workspace-types.js.map +0 -1
  715. package/dist/workspace.js +0 -443
  716. package/dist/workspace.js.map +0 -1
@@ -0,0 +1,583 @@
1
+ // Focused unit test for the orchestrator loop's worker.cancel interpretation
2
+ // (src/shell/orchestrator-loop.ts). The reducer EMITS a `worker.cancel` effect for
3
+ // an operator move onto a live attempt (issue 199); the loop is the ONE place that
4
+ // interprets it, performing the cancel via its own terminateRunning — the same path
5
+ // the stall reaper drives. core holds no live handles, so this is the loop's job.
6
+ //
7
+ // We drive the loop with a stubbed pure reducer so the test exercises only the
8
+ // effect-interpreter seam: seed a running entry via a dispatch plan, then fold an
9
+ // event whose result carries a worker.cancel effect, and assert the live entry's
10
+ // cancel closure fired and the workspace-cleanup flag was set from the effect.
11
+ import { test } from 'node:test';
12
+ import assert from 'node:assert/strict';
13
+ import { OrchestratorLoop } from '../../src/shell/orchestrator-loop.js';
14
+ import { decideReconcileForIssue } from '../../src/core/schedule/reconcile-issue.js';
15
+ import { tick } from '../../src/core/schedule/tick.js';
16
+ const POLL_TIMER_ID = 'orchestrator_poll';
17
+ function tickConfig() {
18
+ return {
19
+ pollIntervalMs: 5_000,
20
+ staticCap: 3,
21
+ memoryAdmissionEnabled: false,
22
+ hostMemoryReserveMib: 0,
23
+ perVmMib: 0,
24
+ maxRetryBackoffMs: 60_000,
25
+ circuitBreakerThreshold: 0,
26
+ activeStates: new Set(['todo']),
27
+ terminalStates: new Set(['done']),
28
+ states: { Todo: { role: 'active' }, Done: { role: 'terminal' } },
29
+ spawn: { spawnState: null, onIdle: false, afterTerminal: 0, title: 'Reflection {{ stamp }}', body: null, maxInFlight: 1 },
30
+ holdingState: null,
31
+ };
32
+ }
33
+ function issue(id) {
34
+ return {
35
+ id, identifier: id, title: id, description: null, priority: null, state: 'Todo',
36
+ branch_name: null, url: null, labels: [], blocked_by: [], created_at: null, updated_at: null,
37
+ };
38
+ }
39
+ /** A minimal RunningEntry whose cancel closure records its invocation. */
40
+ function buildEntry(plan, cancel) {
41
+ let cancelled = false;
42
+ const entry = {
43
+ issue_id: plan.issue.id,
44
+ identifier: plan.issue.identifier,
45
+ issue: plan.issue,
46
+ cleanup_workspace_on_exit: false,
47
+ cancel: () => {
48
+ cancelled = true;
49
+ cancel();
50
+ },
51
+ };
52
+ return { entry, cancelled: () => cancelled };
53
+ }
54
+ /**
55
+ * Build a loop wired to a programmable reducer. `results` is consumed one per
56
+ * dispatch; everything the loop needs from the composition root is a thin stub
57
+ * (no timers fire — start() is never called).
58
+ */
59
+ function makeLoop(results, extra = {}) {
60
+ const entries = [];
61
+ const executed = [];
62
+ const snapshots = [];
63
+ let i = 0;
64
+ const deps = {
65
+ tick: (event, snapshot) => {
66
+ executed.push(event);
67
+ snapshots.push(snapshot);
68
+ return results[i++] ?? { dispatch: [], effects: [], claim: [], release: [] };
69
+ },
70
+ interpreter: { execute: async () => ({ ok: true }) },
71
+ timers: { sleep: async () => undefined, setTimer: () => undefined, clearTimer: () => undefined },
72
+ memProbe: { read: () => null },
73
+ clock: { now: () => 1_700_000_000_000, iso: () => '2023-11-14T22:13:20.000Z' },
74
+ readConfig: () => tickConfig(),
75
+ // Default to a tracker miss (poll bails right after the move-reconcile); a test
76
+ // that drives a real poll-tick fold overrides this via `extra`.
77
+ fetchCandidates: async () => null,
78
+ ...extra,
79
+ runWorker: () => new Promise(() => undefined), // never resolves ⇒ entry stays live
80
+ buildEntry: (plan, cancel) => {
81
+ const built = buildEntry(plan, cancel);
82
+ entries.push(built);
83
+ return built.entry;
84
+ },
85
+ tokenFold: {},
86
+ stall: { detectStall: () => ({ stalled: false }), stallTimeoutMs: () => 0 },
87
+ backoff: () => 0,
88
+ pollTimerId: POLL_TIMER_ID,
89
+ spawnActor: 'symphony/sleep-cycle',
90
+ };
91
+ return { loop: new OrchestratorLoop(deps), entries, executed, snapshots };
92
+ }
93
+ /** Seed one live running entry into the loop via the first (dispatch-plan) result. */
94
+ function seedRunning(loop) {
95
+ // Any event triggers the fold; the stubbed reducer returns the queued dispatch
96
+ // plan, so the loop spawns the (never-resolving) worker and keeps the entry live.
97
+ loop.dispatch({ kind: 'operator_nudge' });
98
+ }
99
+ test('worker.cancel onto a terminal target fires the live cancel closure AND sets the cleanup flag', () => {
100
+ const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
101
+ const { loop, entries } = makeLoop([
102
+ { dispatch: [plan], effects: [], claim: ['i1'], release: [] },
103
+ {
104
+ dispatch: [],
105
+ effects: [{ family: 'worker', kind: 'cancel', issueId: 'i1', cleanupWorkspace: true }],
106
+ claim: [],
107
+ release: [],
108
+ },
109
+ ]);
110
+ seedRunning(loop);
111
+ assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
112
+ const { entry, cancelled } = entries[0];
113
+ // Fold the operator_move-shaped result whose effect is worker.cancel.
114
+ loop.dispatch({ kind: 'operator_move', issueId: 'i1', identifier: 'i1', toState: 'Done', toTerminal: true, toActive: false });
115
+ assert.equal(cancelled(), true, 'the live cancel closure fired');
116
+ assert.equal(entry.cleanup_workspace_on_exit, true, 'a terminal target flags workspace cleanup');
117
+ });
118
+ test('worker.cancel onto an active target cancels WITHOUT flagging workspace cleanup', () => {
119
+ const plan = { issue: issue('i2'), attempt: null, trackerRoot: '/tracker' };
120
+ const { loop, entries } = makeLoop([
121
+ { dispatch: [plan], effects: [], claim: ['i2'], release: [] },
122
+ {
123
+ dispatch: [],
124
+ effects: [{ family: 'worker', kind: 'cancel', issueId: 'i2', cleanupWorkspace: false }],
125
+ claim: [],
126
+ release: [],
127
+ },
128
+ ]);
129
+ seedRunning(loop);
130
+ const { entry, cancelled } = entries[0];
131
+ loop.dispatch({ kind: 'operator_move', issueId: 'i2', identifier: 'i2', toState: 'Review', toTerminal: false, toActive: true });
132
+ assert.equal(cancelled(), true, 'the live cancel closure fired');
133
+ assert.equal(entry.cleanup_workspace_on_exit, false, 'an active target keeps the workspace for the redispatch');
134
+ });
135
+ test('worker.cancel for an issue with no live entry is a safe no-op', () => {
136
+ const { loop, entries } = makeLoop([
137
+ {
138
+ dispatch: [],
139
+ effects: [{ family: 'worker', kind: 'cancel', issueId: 'ghost', cleanupWorkspace: true }],
140
+ claim: [],
141
+ release: [],
142
+ },
143
+ ]);
144
+ // No dispatch plan seeded ⇒ nothing in the running map; terminateRunning no-ops.
145
+ loop.dispatch({ kind: 'operator_move', issueId: 'ghost', identifier: 'ghost', toState: 'Done', toTerminal: true, toActive: false });
146
+ assert.equal(entries.length, 0);
147
+ assert.equal(loop.runningEntries().length, 0);
148
+ });
149
+ // ─── sleep-cycle recurring spawn: success-gated counter reset ───────────────
150
+ // The reducer EMITS a tracker.write_issue create effect (actor = the spawn actor)
151
+ // and optimistically resets the doneSinceReflect counter to 0; the loop routes
152
+ // that effect through the guarded mint path, which restores the PRE-reset counter
153
+ // if the create fails. We observe the counter via the NEXT fold's snapshot.
154
+ const SPAWN_ACTOR = 'symphony/sleep-cycle';
155
+ function writeIssueResult() {
156
+ return {
157
+ dispatch: [],
158
+ effects: [
159
+ {
160
+ family: 'tracker',
161
+ kind: 'write_issue',
162
+ trackerRoot: '/tracker',
163
+ state: 'Reflect',
164
+ title: 'Reflection 2023-11-14 22:13',
165
+ description: 'Auto-spawned reflection cycle.',
166
+ actor: SPAWN_ACTOR,
167
+ },
168
+ ],
169
+ claim: [],
170
+ release: [],
171
+ doneSinceReflect: 0, // core's optimistic reset
172
+ };
173
+ }
174
+ test('spawn mint: a SUCCESSFUL create keeps the counter reset to 0', async () => {
175
+ const { loop, snapshots } = makeLoop([
176
+ { dispatch: [], effects: [], claim: [], release: [], doneSinceReflect: 5 }, // seed the counter
177
+ writeIssueResult(),
178
+ ], { interpreter: { execute: async () => ({ kind: 'write_issue', path: '/tracker/Reflect/1.md', identifier: '1', state: 'Reflect' }) } });
179
+ loop.dispatch({ kind: 'operator_nudge' }); // counter → 5
180
+ loop.dispatch({ kind: 'operator_nudge' }); // counter → 0 + run the (successful) mint
181
+ await new Promise((resolve) => setTimeout(resolve, 0));
182
+ loop.dispatch({ kind: 'operator_nudge' }); // observe via the next snapshot
183
+ assert.equal(snapshots.at(-1).doneSinceReflect, 0, 'a successful mint leaves the counter reset');
184
+ });
185
+ test('spawn mint: a FAILED create restores the pre-reset counter', async () => {
186
+ const { loop, snapshots } = makeLoop([
187
+ { dispatch: [], effects: [], claim: [], release: [], doneSinceReflect: 5 }, // seed the counter
188
+ writeIssueResult(),
189
+ ], { interpreter: { execute: async () => ({ ok: false, error: 'disk full' }) } });
190
+ loop.dispatch({ kind: 'operator_nudge' }); // counter → 5
191
+ loop.dispatch({ kind: 'operator_nudge' }); // counter → 0 then RESTORE to 5 (mint failed)
192
+ await new Promise((resolve) => setTimeout(resolve, 0));
193
+ loop.dispatch({ kind: 'operator_nudge' }); // observe via the next snapshot
194
+ assert.equal(snapshots.at(-1).doneSinceReflect, 5, 'a failed mint restores the accumulated count');
195
+ });
196
+ // ─── pending-mint guard: an in-flight (unlanded) write_issue counts toward max_in_flight ──
197
+ // Review finding (Review→Todo): the immortal-ticket `armingReflection` latch was
198
+ // removed, and core's `max_in_flight` guard only counts issues VISIBLE in the on-disk
199
+ // candidate scan + the running set. A `write_issue` the loop has emitted but whose disk
200
+ // write hasn't landed yet is in NEITHER, so a worker exit + poll racing between emit and
201
+ // landing could mint a SECOND reflection. The shell now surfaces an in-flight mint as
202
+ // `pendingSpawnMints`; this drives the REAL reducer end-to-end (not a stub) to prove the
203
+ // race is closed.
204
+ /** A spawn-configured TickConfig: Reflect mints on a single terminal transition. */
205
+ function spawnTickConfig() {
206
+ return {
207
+ ...tickConfig(),
208
+ activeStates: new Set(['todo', 'reflect']),
209
+ terminalStates: new Set(['done', 'reflected']),
210
+ states: { Todo: { role: 'active' }, Reflect: { role: 'active' }, Reflected: { role: 'terminal' }, Done: { role: 'terminal' } },
211
+ spawn: { spawnState: 'Reflect', onIdle: false, afterTerminal: 1, title: 'Reflection {{ stamp }}', body: null, maxInFlight: 1 },
212
+ };
213
+ }
214
+ /** A clean worker exit carrying a TERMINAL transition OUT of an active state (bumps the counter). */
215
+ function terminalExit(issueId) {
216
+ return {
217
+ ...exitEvent(issueId),
218
+ targetState: 'Done',
219
+ progress: {
220
+ issue_id: issueId,
221
+ identifier: issueId,
222
+ last_transition: { from_state: 'Todo', to_state: 'Done', notes: '', actor: null, terminal: true },
223
+ },
224
+ };
225
+ }
226
+ test('spawn mint: an in-flight (unlanded) write_issue suppresses a second mint across a racing poll (max_in_flight)', async () => {
227
+ const writes = [];
228
+ const seen = [];
229
+ let releaseWrite;
230
+ // The mint's disk write is HELD unresolved for the whole race window below.
231
+ const held = new Promise((resolve) => {
232
+ releaseWrite = () => resolve({ ok: true });
233
+ });
234
+ const interpreter = {
235
+ execute: async (effect) => {
236
+ if (effect.family === 'tracker' && effect.kind === 'write_issue') {
237
+ writes.push(effect.state);
238
+ return held; // never lands during the test ⇒ the mint stays pending
239
+ }
240
+ return { ok: true };
241
+ },
242
+ };
243
+ const { loop } = makeLoop([], {
244
+ readConfig: spawnTickConfig,
245
+ // Record every snapshot the REAL reducer folds, then delegate to it.
246
+ tick: (event, snap) => {
247
+ seen.push(snap);
248
+ return tick(event, snap);
249
+ },
250
+ fetchCandidates: async () => ({ issues: [], root: '/tracker' }),
251
+ interpreter,
252
+ });
253
+ // 1. A finished non-reflection issue bumps the terminal counter to the threshold.
254
+ loop.onWorkerExit(terminalExit('w1'));
255
+ // 2. Poll: the done-threshold trigger mints exactly one reflection; its write is HELD.
256
+ await pollOnce(loop);
257
+ assert.equal(writes.length, 1, 'the first poll minted exactly one reflection');
258
+ // 3. Another finished issue pushes the counter back over the threshold WHILE the first
259
+ // mint is still in flight (not yet on disk, not running, not a candidate).
260
+ loop.onWorkerExit(terminalExit('w2'));
261
+ // 4. Poll again: the in-flight mint is invisible to the candidate scan + running set,
262
+ // but `pendingSpawnMints` keeps it in the max_in_flight count ⇒ no second write.
263
+ await pollOnce(loop);
264
+ assert.equal(writes.length, 1, 'the in-flight mint suppressed a second reflection');
265
+ assert.equal(seen.at(-1).pendingSpawnMints, 1, 'the racing poll saw the pending mint in its snapshot');
266
+ // Let the held write settle so the pending count drops (no leak) before the test ends.
267
+ releaseWrite();
268
+ await new Promise((resolve) => setTimeout(resolve, 0));
269
+ });
270
+ // ─── per-poll cancel-on-move reconcile (issue 211) ──────────────────────────
271
+ // The poll loop reconciles every LIVE running entry against its FRESH tracker view
272
+ // via the REAL decideReconcileForIssue (wired from production), so a disk `mv` /
273
+ // external move out of an active state cancels the in-flight attempt even when no
274
+ // dashboard move-event fired. We seed a live entry, hand the loop a fresh view
275
+ // through fetchRunningViews, drive ONE poll (fetchCandidates returns null so the poll
276
+ // bails right after the reconcile), and assert the cancel/cleanup/refresh decision.
277
+ const RECONCILE_STATES = {
278
+ Todo: { role: 'active' },
279
+ Triage: { role: 'holding' },
280
+ Done: { role: 'terminal' },
281
+ };
282
+ /** Invoke the private poll once (the production path that fires reconcileRunning). */
283
+ function pollOnce(loop) {
284
+ return loop.poll();
285
+ }
286
+ function freshIssue(state) {
287
+ return { ...issue('i1'), state };
288
+ }
289
+ /**
290
+ * Seed one live `i1` entry, then drive a poll whose move-reconcile sees `fresh`
291
+ * (or, when undefined, an EMPTY map ⇒ `i1` is missing from the tracker). Returns the
292
+ * seeded entry handle so the test can assert cancel/cleanup/refresh.
293
+ */
294
+ async function reconcilePoll(fresh) {
295
+ const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
296
+ const { loop, entries } = makeLoop([{ dispatch: [plan], effects: [], claim: ['i1'], release: [] }], {
297
+ readConfig: () => ({ ...tickConfig(), states: RECONCILE_STATES }),
298
+ reconcileIssue: decideReconcileForIssue,
299
+ fetchRunningViews: async () => new Map(fresh ? [['i1', fresh]] : []),
300
+ });
301
+ seedRunning(loop);
302
+ assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
303
+ await pollOnce(loop);
304
+ return entries[0];
305
+ }
306
+ test('poll reconcile: a running entry moved to a HOLDING state is cancelled WITHOUT cleanup (issue 211)', async () => {
307
+ const { entry, cancelled } = await reconcilePoll(freshIssue('Triage'));
308
+ assert.equal(cancelled(), true, 'the move out of an active state cancelled the live attempt');
309
+ assert.equal(entry.cleanup_workspace_on_exit, false, 'a holding target keeps the workspace');
310
+ });
311
+ test('poll reconcile: a running entry moved to a TERMINAL state is cancelled WITH cleanup (issue 211)', async () => {
312
+ const { entry, cancelled } = await reconcilePoll(freshIssue('Done'));
313
+ assert.equal(cancelled(), true, 'the move to a terminal state cancelled the live attempt');
314
+ assert.equal(entry.cleanup_workspace_on_exit, true, 'a terminal-role target reaps the workspace');
315
+ });
316
+ test('poll reconcile: a running entry still in an ACTIVE state is refreshed, NOT cancelled (issue 211)', async () => {
317
+ const refreshed = { ...freshIssue('Todo'), title: 'fresh title' };
318
+ const { entry, cancelled } = await reconcilePoll(refreshed);
319
+ assert.equal(cancelled(), false, 'an active fresh state keeps the attempt running');
320
+ assert.equal(entry.issue.title, 'fresh title', 'the in-memory snapshot was refreshed from the fresh view');
321
+ });
322
+ test('poll reconcile: a running entry missing from the tracker is terminated WITHOUT cleanup (issue 211)', async () => {
323
+ const { entry, cancelled } = await reconcilePoll(undefined);
324
+ assert.equal(cancelled(), true, 'a vanished tracker row terminates the live attempt');
325
+ assert.equal(entry.cleanup_workspace_on_exit, false, 'a missing row leaves the workspace (safety)');
326
+ });
327
+ test('poll reconcile: an entry the agent itself transitioned is SKIPPED (worker_exit owns cleanup) (issue 211)', async () => {
328
+ const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
329
+ let viewsFetched = 0;
330
+ const { loop, entries } = makeLoop([{ dispatch: [plan], effects: [], claim: ['i1'], release: [] }], {
331
+ readConfig: () => ({ ...tickConfig(), states: RECONCILE_STATES }),
332
+ reconcileIssue: decideReconcileForIssue,
333
+ fetchRunningViews: async () => {
334
+ viewsFetched += 1;
335
+ return new Map([['i1', freshIssue('Done')]]);
336
+ },
337
+ });
338
+ seedRunning(loop);
339
+ entries[0].entry.transitioned = true; // the agent transitioned to Done itself
340
+ await pollOnce(loop);
341
+ assert.equal(entries[0].cancelled(), false, 'a self-transitioned entry is not re-cancelled by the net');
342
+ assert.equal(viewsFetched, 0, 'no fresh-view fetch when every running entry already transitioned');
343
+ });
344
+ test('image.ensure runs the converter, exposes the build banner state, then marks the ref ready (issue 206)', async () => {
345
+ let resolveBuild;
346
+ const buildDone = new Promise((res) => {
347
+ resolveBuild = res;
348
+ });
349
+ let ensureCalls = 0;
350
+ const ref = 'ghcr.io/acme/agent:1';
351
+ // Readiness is digest-based: the probe resolves the ref's CURRENT digest + looks up
352
+ // its cached selector from a store the converter populates (issue 206 rework). Here
353
+ // the digest is fixed; the store is empty until the (gated) build finishes.
354
+ const store = new Map(); // digest → selector
355
+ const digest = 'sha256:AAAA';
356
+ const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
357
+ const { loop, snapshots } = makeLoop([
358
+ // The reducer emitted an ensure_image effect (oci_image set + not yet converted).
359
+ { dispatch: [], effects: [{ family: 'image', kind: 'ensure', ref }], claim: [], release: [] },
360
+ ], {
361
+ readConfig: ociCfg,
362
+ probeImage: (r) => {
363
+ assert.equal(r, ref);
364
+ return { digest, selector: store.get(digest) ?? null };
365
+ },
366
+ ensureImage: async (r) => {
367
+ ensureCalls += 1;
368
+ assert.equal(r, ref);
369
+ await buildDone;
370
+ const selector = 'build-converted-1';
371
+ store.set(digest, selector); // the converter tagged the asset at this digest
372
+ return selector;
373
+ },
374
+ });
375
+ loop.dispatch({ kind: 'operator_nudge' });
376
+ // Before the build resolves, the probe finds no cached asset → no selector to boot.
377
+ assert.equal(loop.effectiveImageSelector(), null);
378
+ // The converter fired once (the effect ran in applyResult) and is in flight →
379
+ // the dashboard banner state is live. (The snapshot the reducer just folded was
380
+ // built BEFORE the effect ran, so its `building` is still false — the in-flight
381
+ // hold shows on the NEXT fold below.)
382
+ assert.equal(ensureCalls, 1);
383
+ assert.deepEqual(loop.imageBuildState(), {
384
+ ref,
385
+ since: '2023-11-14T22:13:20.000Z',
386
+ });
387
+ assert.equal(snapshots.at(-1).image?.ociConfigured, true);
388
+ assert.equal(snapshots.at(-1).image?.ready, false);
389
+ // A fold while the build is in flight sees `building: true` (the gate holds) and
390
+ // does NOT probe the half-written store.
391
+ loop.dispatch({ kind: 'operator_nudge' });
392
+ assert.equal(snapshots.at(-1).image?.building, true);
393
+ assert.equal(snapshots.at(-1).image?.ready, false);
394
+ assert.equal(ensureCalls, 1, 'no second converter run while one is in flight');
395
+ // Finish the build; drain microtasks so ensureImage's continuation runs.
396
+ resolveBuild();
397
+ await new Promise((resolve) => setTimeout(resolve, 0));
398
+ // Banner cleared; a fresh fold re-probes and now finds the cached asset (gate releases).
399
+ assert.equal(loop.imageBuildState(), null);
400
+ loop.dispatch({ kind: 'operator_nudge' });
401
+ assert.equal(snapshots.at(-1).image?.ready, true);
402
+ assert.equal(snapshots.at(-1).image?.building, false);
403
+ // The converter's resolved selector is now live: the runner threads this into the
404
+ // VmPlan so a workflow that sets only `oci_image` boots the cached asset (#206).
405
+ assert.equal(loop.effectiveImageSelector(), 'build-converted-1');
406
+ });
407
+ test('image readiness is digest-based: a moving tag whose digest changed reconverts (issue 206 rework)', async () => {
408
+ // The blocker the prior review flagged: readiness keyed on the ref STRING reported
409
+ // "ready" forever once a ref converted once, so a moving tag (`repo:latest`) whose
410
+ // underlying image changed kept booting the stale selector. Here the SAME ref
411
+ // resolves first to digest A (selector A), then to digest B — and reconcile must
412
+ // stop dispatching A, hold + ensure for B, and resume with selector B.
413
+ const ref = 'repo:latest';
414
+ const store = new Map(); // digest → selector (the converter's cache)
415
+ let currentDigest = 'sha256:AAAA';
416
+ const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
417
+ const ensure = () => ({
418
+ dispatch: [],
419
+ effects: [{ family: 'image', kind: 'ensure', ref }],
420
+ claim: [],
421
+ release: [],
422
+ });
423
+ const idle = () => ({ dispatch: [], effects: [], claim: [], release: [] });
424
+ const { loop, snapshots } = makeLoop([ensure(), idle(), idle(), ensure(), idle()], {
425
+ readConfig: ociCfg,
426
+ probeImage: () => ({ digest: currentDigest, selector: store.get(currentDigest) ?? null }),
427
+ ensureImage: async () => {
428
+ const selector = `selector-${currentDigest}`;
429
+ store.set(currentDigest, selector); // convert + tag the asset at the live digest
430
+ return selector;
431
+ },
432
+ });
433
+ // Tick 1: digest A, nothing cached → core emits ensure (we drive it via the canned
434
+ // result); the converter builds + tags A. Drain microtasks so it completes.
435
+ loop.dispatch({ kind: 'operator_nudge' });
436
+ assert.equal(snapshots.at(-1).image?.ready, false);
437
+ await new Promise((resolve) => setTimeout(resolve, 0));
438
+ // Tick 2: a fresh probe finds A cached → ready, and dispatch boots selector A.
439
+ loop.dispatch({ kind: 'operator_nudge' });
440
+ assert.equal(snapshots.at(-1).image?.ready, true);
441
+ assert.equal(loop.effectiveImageSelector(), 'selector-sha256:AAAA');
442
+ // The tag MOVES: the same ref now resolves to digest B (B is not yet converted).
443
+ currentDigest = 'sha256:BBBB';
444
+ // Tick 3: readiness re-probes the LIVE digest → B has no cached asset → NOT ready,
445
+ // so the gate holds dispatch and effectiveImageSelector drops the stale A selector.
446
+ loop.dispatch({ kind: 'operator_nudge' });
447
+ assert.equal(snapshots.at(-1).image?.ready, false, 'stale digest A is no longer reported ready');
448
+ assert.equal(snapshots.at(-1).image?.building, false);
449
+ assert.equal(snapshots.at(-1).image?.failed, false, 'a fresh digest is not failure-suppressed');
450
+ assert.equal(loop.effectiveImageSelector(), null, 'dispatch stops booting the stale selector A');
451
+ // Tick 4: core emits ensure for B (canned); the converter builds + tags B.
452
+ loop.dispatch({ kind: 'operator_nudge' });
453
+ await new Promise((resolve) => setTimeout(resolve, 0));
454
+ // Tick 5: B is now cached → ready again, and dispatch resumes with selector B.
455
+ loop.dispatch({ kind: 'operator_nudge' });
456
+ assert.equal(snapshots.at(-1).image?.ready, true);
457
+ assert.equal(loop.effectiveImageSelector(), 'selector-sha256:BBBB', 'dispatch resumes with the new digest B selector');
458
+ });
459
+ test('image conversion failure: the failure banner stays visible while dispatch is held, then a moved tag clears it (issue 206 review)', async () => {
460
+ // The blocker the prior review flagged: a failed conversion cleared the in-flight
461
+ // build state but left dispatch HELD with NO dashboard-visible failure. Here the
462
+ // converter THROWS; the loop must (a) clear the in-flight banner, (b) expose a
463
+ // persistent failure banner carrying the ref + error, and (c) keep readiness
464
+ // `failed` so the core gate holds dispatch + suppresses an auto-retry — until the
465
+ // tag moves to a fresh digest, which supersedes the failure and lets the gate retry.
466
+ const ref = 'ghcr.io/acme/agent:1';
467
+ let currentDigest = 'sha256:AAAA';
468
+ const ociCfg = () => ({ ...tickConfig(), ociImage: ref });
469
+ const idle = () => ({ dispatch: [], effects: [], claim: [], release: [] });
470
+ const ensure = () => ({
471
+ dispatch: [],
472
+ effects: [{ family: 'image', kind: 'ensure', ref }],
473
+ claim: [],
474
+ release: [],
475
+ });
476
+ let ensureCalls = 0;
477
+ const { loop, snapshots } = makeLoop([ensure(), idle(), idle()], {
478
+ readConfig: ociCfg,
479
+ probeImage: () => ({ digest: currentDigest, selector: null }), // never cached (the build fails)
480
+ ensureImage: async () => {
481
+ ensureCalls += 1;
482
+ throw new Error('manifest unknown');
483
+ },
484
+ });
485
+ // Tick 1: core emitted ensure (canned); the converter runs and THROWS. Drain microtasks.
486
+ loop.dispatch({ kind: 'operator_nudge' });
487
+ assert.equal(ensureCalls, 1);
488
+ await new Promise((resolve) => setTimeout(resolve, 0));
489
+ // The in-flight banner cleared, but the failure banner is now live with ref + error.
490
+ assert.equal(loop.imageBuildState(), null, 'the in-flight build banner cleared');
491
+ assert.deepEqual(loop.imageFailureState(), {
492
+ ref,
493
+ since: '2023-11-14T22:13:20.000Z',
494
+ message: 'manifest unknown',
495
+ });
496
+ // Tick 2: a fresh fold re-probes the SAME digest → still not cached → readiness
497
+ // reports `failed` (the core gate then holds dispatch + suppresses an auto-retry,
498
+ // covered by image-decide.test.ts), and the failure banner stays visible.
499
+ loop.dispatch({ kind: 'operator_nudge' });
500
+ assert.equal(snapshots.at(-1).image?.ready, false);
501
+ assert.equal(snapshots.at(-1).image?.failed, true, 'a failed digest keeps dispatch held + suppresses re-emit');
502
+ assert.equal(loop.imageFailureState()?.message, 'manifest unknown', 'the failure banner persists while held');
503
+ assert.equal(ensureCalls, 1, 'no auto-retry while the same digest is failure-suppressed');
504
+ // The tag MOVES to a fresh digest: the failure is superseded → readiness flips off
505
+ // `failed` (so the gate re-emits ensure) and the failure banner clears.
506
+ currentDigest = 'sha256:BBBB';
507
+ loop.dispatch({ kind: 'operator_nudge' });
508
+ assert.equal(snapshots.at(-1).image?.failed, false, 'a fresh digest is not failure-suppressed');
509
+ assert.equal(loop.imageFailureState(), null, 'the failure banner cleared once the digest moved');
510
+ });
511
+ test('both image keys set: the snapshot carries the escape hatch so the gate can give it precedence (issue 206)', () => {
512
+ // The prior review's blocker: the poll snapshot only fed core the oci_image
513
+ // readiness, so a not-yet-converted oci_image held dispatch even when the
514
+ // `gondolin.image` escape hatch was set and WINS the runtime selector. The loop's
515
+ // job is to BUILD the snapshot; the reducer (tick.test.ts) decides. Here we prove
516
+ // the snapshot now carries BOTH selectors, so the real reducer can short-circuit.
517
+ const ref = 'ghcr.io/acme/agent:1';
518
+ const bothCfg = () => ({ ...tickConfig(), image: 'prebuilt-asset:1', ociImage: ref });
519
+ let probes = 0;
520
+ const { loop, snapshots } = makeLoop([], {
521
+ readConfig: bothCfg,
522
+ // oci_image is NOT converted (no cached selector) — yet the escape hatch wins.
523
+ probeImage: () => {
524
+ probes += 1;
525
+ return { digest: 'sha256:AAAA', selector: null };
526
+ },
527
+ });
528
+ loop.dispatch({ kind: 'operator_nudge' });
529
+ const snap = snapshots.at(-1);
530
+ // The escape hatch rides in the reducer's config input (so it can take precedence)…
531
+ assert.equal(snap.cfg.image, 'prebuilt-asset:1');
532
+ assert.equal(snap.cfg.ociImage, ref);
533
+ // …alongside the (not-ready) oci readiness the shell still projects.
534
+ assert.equal(snap.image?.ociConfigured, true);
535
+ assert.equal(snap.image?.ready, false);
536
+ assert.ok(probes >= 1, 'the shell projected the oci readiness for the reducer to weigh');
537
+ });
538
+ /** A worker-exit event for the seeded entry; the breaker/retry fields are inert here. */
539
+ function exitEvent(issueId) {
540
+ return {
541
+ kind: 'worker_exit',
542
+ issueId,
543
+ identifier: issueId,
544
+ normal: true,
545
+ reason: 'done',
546
+ priorAttempt: null,
547
+ targetState: 'Review',
548
+ progress: { issue_id: issueId, identifier: issueId, last_transition: null },
549
+ trackerRootAtDispatch: '/tracker',
550
+ resolvedActor: null,
551
+ };
552
+ }
553
+ test('onWorkerExit removes the live entry (frees the slot) and folds the exit excluding it', () => {
554
+ const plan = { issue: issue('i1'), attempt: null, trackerRoot: '/tracker' };
555
+ const { loop, executed, snapshots } = makeLoop([
556
+ { dispatch: [plan], effects: [], claim: ['i1'], release: [] },
557
+ // The worker_exit fold result — its exact shape is core's job (tick.test.ts);
558
+ // here we assert the loop removed the entry and folded the exit through core.
559
+ { dispatch: [], effects: [], claim: [], release: [], breaker: { op: 'clear', issueId: 'i1' } },
560
+ ]);
561
+ seedRunning(loop);
562
+ assert.equal(loop.runningEntries().length, 1, 'the dispatch plan seeded a live entry');
563
+ loop.onWorkerExit(exitEvent('i1'));
564
+ // The entry was removed (slot freed) BEFORE the reducer folded the exit, so the
565
+ // snapshot the reducer saw — and thus its slot accounting — excludes it.
566
+ assert.equal(loop.runningEntries().length, 0, 'worker exit removed the entry, freeing its slot');
567
+ assert.equal(executed.at(-1)?.kind, 'worker_exit', 'the exit folded through the reducer');
568
+ assert.ok(!snapshots.at(-1).running.some((r) => r.issue_id === 'i1'), 'the folded snapshot excluded the exited entry');
569
+ });
570
+ test('onWorkerExit after stop(): drops claim + entry without folding a retry', () => {
571
+ const plan = { issue: issue('i2'), attempt: null, trackerRoot: '/tracker' };
572
+ const { loop, executed } = makeLoop([
573
+ { dispatch: [plan], effects: [], claim: ['i2'], release: [] },
574
+ ]);
575
+ seedRunning(loop);
576
+ assert.equal(loop.runningEntries().length, 1);
577
+ loop.stop(); // races the worker unwind; running map is cleared here
578
+ loop.onWorkerExit(exitEvent('i2'));
579
+ // stop() already cleared running; the exit must not fold a new tick (no retry armed).
580
+ assert.equal(loop.runningEntries().length, 0);
581
+ assert.equal(executed.filter((e) => e.kind === 'worker_exit').length, 0, 'no fold after stop()');
582
+ });
583
+ //# sourceMappingURL=orchestrator-loop.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator-loop.test.js","sourceRoot":"","sources":["../../../tests/shell/orchestrator-loop.test.ts"],"names":[],"mappings":"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"}