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
@@ -1,375 +0,0 @@
1
- // Gondolin dispatch orchestration — the Gondolin VM bring-up +
2
- // exec-launch + teardown sequence (runner.ts
3
- // `startVmOrFail`/`launchExecStream`/`attachStderrTap` + teardown), composed over
4
- // the injected `VmClient` port, the host `CredentialSecretRegistry`, and gondolin's
5
- // `createHttpHooks`. This is the `application`-role composition seam: it wires the
6
- // credential adapter + the VM port + the ACP bridge mapping together.
7
- //
8
- // LIVE: the live dispatch path (`runner.ts` runAttempt etc.) imports this.
9
- // Gondolin is the live VM backend. The invariant guards (vm-guards.ts) are
10
- // wired in here so the Gondolin
11
- // path is enforced-by-construction: mounts are validated and env is stripped while
12
- // the `CreateVmOptions` are built — a credential mount HARD-FAILs and a credential
13
- // env var can never reach the guest's PID-1 environment.
14
- //
15
- // Contract mirrored from the live runner (without modifying it):
16
- // - mounts: workspace RW + gondolin.volumes + eval-mode RO (buildVmMounts) — here the
17
- // caller passes the already-built list; we validate it.
18
- // - env: forwarded env (buildForwardedEnv) — here generalized via stripCredentialEnv.
19
- // - launch: `node /opt/symphony/vm-agent.mjs` (the in-VM ACP launcher), stdin
20
- // end()ed immediately (ACP rides the TCP bridge, not stdio), stderr tapped before
21
- // the bridge handshake (attachStderrTap).
22
- // - teardown: kill the exec, close the VM, deregister the secret manager —
23
- // idempotent and error-tolerant.
24
- import { Buffer } from 'node:buffer';
25
- import { createHttpHooks } from '@earendil-works/gondolin';
26
- import { log } from '../logging.js';
27
- import { SYMPHONY_VM_PREFIX, } from './vm-port.js';
28
- import { buildAcpTcpDns, buildMcpTcpHostEntry } from './vm-acp-mapping.js';
29
- import { assertNoCredentialMounts, stripCredentialEnv, stripCredentialTokenVars, } from './vm-guards.js';
30
- import { buildGondolinFakeCreds, } from './gondolin-creds-staging.js';
31
- /**
32
- * The in-VM ACP launcher command. Mirrors the earlier dispatch path's
33
- * `exec node /opt/symphony/vm-agent.mjs` (deriveAcpCommand). On Gondolin there is no
34
- * `bash -lc` wrapper and no per-dispatch staged-file `cp` preamble — runtime files
35
- * land via VFS mounts / the baked image — so the launcher is exec'd directly.
36
- */
37
- const VM_AGENT_COMMAND = ['node', '/opt/symphony/vm-agent.mjs'];
38
- /**
39
- * PATH for the launched agent's exec. Gondolin's `vm.exec` runs the command
40
- * WITHOUT a login shell, so the guest's profile-set PATH does not apply — the
41
- * default exec PATH is only `/usr/sbin:/usr/bin:/sbin:/bin`, which EXCLUDES
42
- * `/usr/local/bin` where the image installs `node` and every agent CLI
43
- * (`claude-agent-acp` / `codex-acp` / `opencode`). Without this, the launch
44
- * command `node …` fails to spawn (ENOENT) and the in-VM agent never dials the
45
- * bridge back — and even if `node` were found, the adapter the agent spawns
46
- * (`SYMPHONY_ADAPTER_BIN`, also in `/usr/local/bin`) would not resolve either.
47
- * Set it explicitly on the launch exec env (which the adapter child inherits) so
48
- * the production dispatch path does not depend on a login shell. This carries no
49
- * secret — it is a fixed search path. (Go-live validation finding.)
50
- */
51
- const GUEST_AGENT_PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
52
- /**
53
- * Guest path of the gitconfig the dispatcher stages so in-guest git trusts the
54
- * host-owned, bind-mounted workspace. The workspace dir is owned by the HOST uid
55
- * (e.g. 1000), while in-guest git runs as a DIFFERENT uid — so git's
56
- * CVE-2022-24765 ownership guard FATALs every command (`fatal: detected dubious
57
- * ownership`, exit 128, empty stdout), breaking the in-guest `git rebase` /
58
- * conflict-handoff path. `safe.directory` is honored ONLY from system/global
59
- * config files — NOT from `-c`/command-level config, `GIT_CONFIG_*` injected
60
- * values, or repo-local config — so a global config FILE is the load-bearing
61
- * surface (`buildLaunchEnv` points `GIT_CONFIG_GLOBAL` here). Lives OUTSIDE the
62
- * workspace mount (`/opt/symphony`, the same image dir the launcher lives in) so
63
- * it never shows up in the repo's own `git status`. (Issue 149.)
64
- */
65
- const GUEST_GITCONFIG_PATH = '/opt/symphony/gitconfig';
66
- /**
67
- * Contents of the staged guest gitconfig: disarm git's bind-mount ownership guard
68
- * for every workspace path. `*` (not the per-workspace path) so a re-dispatch into a
69
- * differently-named workspace dir needs no per-issue value. Holds NO secret → 0644.
70
- */
71
- const GUEST_GITCONFIG_CONTENT = '[safe]\n\tdirectory = *\n';
72
- const GUEST_GITCONFIG_MODE = 0o644;
73
- /**
74
- * The staged guest gitconfig as a `GuestCredFile` — written via the SAME
75
- * base64-piped pre-launch write-exec the fake creds use, so it lands before the
76
- * agent's first git command. Carries only the bind-mount trust line, never a secret.
77
- */
78
- function guestGitconfigFile() {
79
- return {
80
- guestPath: GUEST_GITCONFIG_PATH,
81
- content: GUEST_GITCONFIG_CONTENT,
82
- mode: GUEST_GITCONFIG_MODE,
83
- };
84
- }
85
- /** Bound on each fake-creds write exec (a tiny mkdir+write; never hangs). */
86
- const STAGE_TIMEOUT_MS = 15_000;
87
- /**
88
- * Build the in-guest write command for a single fake-creds file. The content is
89
- * base64-encoded host-side and decoded in-guest, so arbitrary JSON (quotes,
90
- * newlines, `$`) can never break out of the shell or be interpreted — there is no
91
- * heredoc/`echo` injection surface. `mkdir -p` the parent, decode into place, then
92
- * `chmod`. POSIX-portable (`/bin/sh`, `base64 -d`). The guest path is single-quoted
93
- * (paths we emit contain no `'`).
94
- */
95
- function writeFileCommand(file) {
96
- const b64 = Buffer.from(file.content, 'utf8').toString('base64');
97
- const dir = posixDirname(file.guestPath);
98
- const mode = file.mode.toString(8);
99
- const script = `mkdir -p '${dir}' && ` +
100
- `printf %s '${b64}' | base64 -d > '${file.guestPath}' && ` +
101
- `chmod ${mode} '${file.guestPath}'`;
102
- return ['/bin/sh', '-c', script];
103
- }
104
- /** POSIX dirname for an absolute guest path (always `/`-separated). */
105
- function posixDirname(p) {
106
- const idx = p.lastIndexOf('/');
107
- if (idx <= 0)
108
- return '/';
109
- return p.slice(0, idx);
110
- }
111
- /**
112
- * Orchestrates a single Gondolin dispatch. Inject the VM port, the host credential
113
- * registry, and the per-adapter hooks config; `dispatch()` builds the enforced
114
- * `CreateVmOptions`, creates the VM, seeds + registers the secret manager BEFORE the
115
- * agent launches, then launches the in-VM ACP agent and returns a teardown handle.
116
- */
117
- export class GondolinDispatcher {
118
- vmClient;
119
- registry;
120
- hooksConfig;
121
- vmConfig;
122
- constructor(vmClient, registry, hooksConfig, vmConfig) {
123
- this.vmClient = vmClient;
124
- this.registry = registry;
125
- this.hooksConfig = hooksConfig;
126
- this.vmConfig = vmConfig;
127
- }
128
- async dispatch(opts) {
129
- // ONE createHttpHooks call yields the httpHooks (into createVm), the
130
- // secretManager (into the registry), AND the placeholder `env` map (the
131
- // token-shaped fake bearer keyed by the secret name) for this VM. They must be
132
- // the same instance — and the placeholder `env` (previously dropped) is the
133
- // value the guest holds, so its fake creds + launch env are built from it.
134
- const { httpHooks, secretManager, env: placeholderEnv } = createHttpHooks(this.hooksConfig.options);
135
- const mapping = buildAcpTcpDns(opts.bridgeHost, opts.bridgePort);
136
- // Add the guest→host MCP control-plane tunnel into the SAME tcp.hosts record
137
- // (the synthetic per-host DNS already resolves both names). Without this the
138
- // agent can run inference turns but cannot reach `symphony.transition` — so it
139
- // completes work but never transitions state (the gap dogfooding surfaced).
140
- if (opts.mcp) {
141
- mapping.tcp = {
142
- ...mapping.tcp,
143
- hosts: { ...mapping.tcp.hosts, ...buildMcpTcpHostEntry(opts.mcp.host, opts.mcp.port) },
144
- };
145
- }
146
- const fakeCreds = await this.buildFakeCreds(opts, placeholderEnv);
147
- // Phase 3 enforcement, BEFORE createVm: a credential mount throws here, and the
148
- // env is stripped so no real token reaches the guest's boot environment.
149
- assertNoCredentialMounts(opts.mounts, opts.mountGuard);
150
- const createOpts = this.buildCreateVmOptions(opts, httpHooks, mapping);
151
- const vm = await this.vmClient.createVm(createOpts);
152
- // Once the VM exists, EVERY subsequent step (register, stage, launch) can
153
- // throw — and the handle (the only teardown affordance) has not been returned
154
- // yet, so a throw here would strand the VM + the registered manager. Guard the
155
- // whole post-createVm bring-up: on any failure close the VM and deregister the
156
- // manager (if it got registered), then rethrow. Cleanup reuses the same
157
- // idempotent, error-tolerant `teardownDispatch` the handle uses.
158
- return this.bringUpOrTeardown(vm, secretManager, fakeCreds, mapping.acpUrl, opts);
159
- }
160
- /**
161
- * Register the secret manager, stage the fake creds, and launch the agent —
162
- * tearing the VM down (and deregistering the manager) on any failure so a
163
- * post-createVm throw can never leak the VM handle the caller never received.
164
- */
165
- async bringUpOrTeardown(vm, secretManager, fakeCreds, acpUrl, opts) {
166
- let registered = null;
167
- try {
168
- // Seed + register the manager BEFORE launching the agent so the placeholder's
169
- // real value is present before the first egress (the registry seeds value '' →
170
- // real token synchronously-after-await). AWAIT it before exec.
171
- registered = await this.registerSecretManager(secretManager);
172
- // Materialize the bind-mount-trust gitconfig (so in-guest git accepts the
173
- // host-owned workspace from its first command — issue 149) PLUS the fake
174
- // native creds files PLUS any non-credential runtime files (model/effort
175
- // knobs) into the guest BEFORE launching the agent — the placeholder bearer
176
- // (a fake) and the effort settings.json must be in place at first read.
177
- await this.stageFakeCredsFiles(vm, [guestGitconfigFile(), ...fakeCreds.files, ...(opts.extraGuestFiles ?? [])], opts.workdir);
178
- const exec = this.launchAgent(vm, opts, acpUrl, fakeCreds.env);
179
- return this.buildHandle(vm, exec, registered, acpUrl, fakeCreds);
180
- }
181
- catch (err) {
182
- // No launch exec yet (or the launch itself threw): close the VM + deregister
183
- // the manager (if registration succeeded). teardownDispatch tolerates a null
184
- // exec and a null registration, so this is safe at any failure point.
185
- await teardownDispatch(vm, null, registered);
186
- throw err;
187
- }
188
- }
189
- /**
190
- * Build the per-adapter fake native creds + placeholder env from the
191
- * placeholder Gondolin minted (`createHttpHooks().env[secretName]`). The
192
- * placeholder is used VERBATIM so it byte-matches what Gondolin substitutes at
193
- * egress; the real token never appears.
194
- */
195
- async buildFakeCreds(opts, placeholderEnv) {
196
- const secretName = this.hooksConfig.secretName;
197
- const placeholder = placeholderEnv[secretName] ?? '';
198
- return buildGondolinFakeCreds(this.hooksConfig.adapterId, {
199
- placeholder,
200
- secretName,
201
- opencodeModel: opts.opencodeModel ?? null,
202
- hostReaders: opts.hostReaders,
203
- });
204
- }
205
- /**
206
- * Write each fake-creds file into the guest via a pre-launch exec. The content
207
- * is base64-piped (no shell-quoting hazard for arbitrary JSON) into a
208
- * `mkdir -p`'d destination, then chmod'd. Gondolin's programmable VFS could also
209
- * host these as mounts, but a write-exec needs no port extension and keeps the
210
- * "placeholder-before-launch" ordering enforced-by-construction here. Each write
211
- * is awaited so the file exists before `vm-agent.mjs` (and the adapter) starts.
212
- */
213
- async stageFakeCredsFiles(vm, files, workdir) {
214
- for (const f of files) {
215
- const exec = vm.exec({
216
- command: writeFileCommand(f),
217
- workdir,
218
- timeoutMs: STAGE_TIMEOUT_MS,
219
- });
220
- exec.stdin.end();
221
- await exec.exit;
222
- }
223
- }
224
- /** Build the enforced `CreateVmOptions`: stripped env, validated mounts, ACP mapping. */
225
- buildCreateVmOptions(opts, httpHooks, mapping) {
226
- return {
227
- imagePath: this.vmConfig.imagePath,
228
- cpus: this.vmConfig.cpus,
229
- memMib: this.vmConfig.memMib,
230
- mounts: opts.mounts,
231
- env: stripCredentialEnv(opts.env),
232
- httpHooks,
233
- tcp: mapping.tcp,
234
- dns: mapping.dns,
235
- // Per-adapter (credential-secrets spec). Default-deny; codex → true because
236
- // codex-acp streams the Responses API over a WS Upgrade. SAFE: Gondolin
237
- // substitutes the real token on the (hookable) Upgrade handshake, so the
238
- // placeholder never egresses, and the post-101 tunnel reaches only the
239
- // allowlisted inference host (a refresh host's upgrade would be blocked). The
240
- // proxy-era #127 wss-leak concern does not apply under Gondolin substitution.
241
- allowWebSockets: this.hooksConfig.allowWebSockets,
242
- sessionLabel: `${SYMPHONY_VM_PREFIX}${opts.identifier}`,
243
- workdir: opts.workdir,
244
- };
245
- }
246
- /** Register the VM's secret manager with the host registry; await the seed. */
247
- async registerSecretManager(manager) {
248
- return this.registry.register({
249
- manager,
250
- secretName: this.hooksConfig.secretName,
251
- adapterId: this.hooksConfig.adapterId,
252
- });
253
- }
254
- /**
255
- * Launch the in-VM ACP agent. Stdin is end()ed immediately — ACP frames ride the
256
- * TCP bridge, not the exec stdio; the exec channel is a process tether + a
257
- * diagnostic-stderr pipe (mirrors launchExecStream + attachStderrTap).
258
- */
259
- launchAgent(vm, opts, acpUrl, placeholderEnv) {
260
- const exec = vm.exec({
261
- command: [...VM_AGENT_COMMAND],
262
- workdir: opts.workdir,
263
- env: this.buildLaunchEnv(opts, acpUrl, placeholderEnv),
264
- timeoutMs: null,
265
- });
266
- exec.stdin.end();
267
- this.attachStderrTap(exec, opts.onStderr);
268
- return exec;
269
- }
270
- /**
271
- * The launch env the in-VM `vm-agent.mjs` reads to dial back + spawn the adapter.
272
- * Runtime env (model/effort/base-url injection) is merged but passed through
273
- * `stripCredentialTokenVars` so an adapter injection can never smuggle a real token
274
- * into the guest while preserving the non-secret vendor-prefixed config knobs
275
- * (`ANTHROPIC_MODEL`, `OPENAI_BASE_URL`, …) the adapter legitimately needs.
276
- *
277
- * ORDERING (load-bearing): the placeholder bearer (a FAKE value keyed by the
278
- * credential var name itself, e.g. `ANTHROPIC_AUTH_TOKEN` / `OPENAI_API_KEY`) is
279
- * merged AFTER `stripCredentialTokenVars` — the strip would otherwise drop it as
280
- * a `*_TOKEN`/`*_API_KEY` name. Spreading it last means the placeholder survives
281
- * the strip while a real token smuggled via `runtimeEnv` (stripped first) cannot.
282
- */
283
- buildLaunchEnv(opts, acpUrl, placeholderEnv) {
284
- return {
285
- // PATH first so a non-login exec resolves `node` + the agent CLIs in
286
- // `/usr/local/bin` (see GUEST_AGENT_PATH). A runtimeEnv-supplied PATH (rare)
287
- // would override it via the spread below.
288
- PATH: GUEST_AGENT_PATH,
289
- // Point git's GLOBAL config at the staged bind-mount-trust gitconfig so
290
- // in-guest git accepts the host-owned workspace from its first command (the
291
- // adapter the agent spawns inherits this exec env — see GUEST_GITCONFIG_PATH).
292
- // Honored as "global" by the CVE-2022-24765 ownership check and
293
- // HOME-independent (this exec sets no HOME). (Issue 149.)
294
- GIT_CONFIG_GLOBAL: GUEST_GITCONFIG_PATH,
295
- SYMPHONY_ACP_URL: acpUrl,
296
- SYMPHONY_ACP_TOKEN: opts.acpToken,
297
- SYMPHONY_ADAPTER_BIN: opts.adapterBin,
298
- SYMPHONY_ADAPTER_ARGS: JSON.stringify(opts.adapterArgs),
299
- ...stripCredentialTokenVars(opts.runtimeEnv),
300
- // The placeholder (a fake) is ADDED after the strip — see the ordering note.
301
- ...placeholderEnv,
302
- };
303
- }
304
- /**
305
- * Pipe the exec's stderr to the caller's sink. Attached before the bridge
306
- * handshake so a pre-connect crash (vm-agent missing, malformed env, adapter that
307
- * exits during startup) still surfaces.
308
- */
309
- attachStderrTap(exec, sink) {
310
- exec.stderr.setEncoding('utf8');
311
- exec.stderr.on('data', (chunk) => {
312
- try {
313
- sink(chunk);
314
- }
315
- catch (err) {
316
- log.warn('gondolin-dispatch: stderr sink threw', { error: err.message });
317
- }
318
- });
319
- }
320
- /** Wrap the live VM + exec + registration into the idempotent teardown handle. */
321
- buildHandle(vm, exec, registered, acpUrl, fakeCreds) {
322
- let torndown = false;
323
- return {
324
- vm,
325
- exec,
326
- acpUrl,
327
- fakeCreds,
328
- teardown: async () => {
329
- if (torndown)
330
- return;
331
- torndown = true;
332
- await teardownDispatch(vm, exec, registered);
333
- },
334
- };
335
- }
336
- }
337
- /**
338
- * Idempotent, error-tolerant teardown: kill the exec, close the VM, deregister the
339
- * secret manager. Each step is independently guarded so one failure does not strand
340
- * the others (mirrors the runner's tearDownSession resilience). `exec` is `null` when
341
- * teardown runs from a bring-up failure that aborted BEFORE the launch exec was
342
- * created, and `registered` is `null` when the secret manager never got registered —
343
- * both are skipped so the partial-bring-up cleanup is safe at any failure point.
344
- */
345
- async function teardownDispatch(vm, exec, registered) {
346
- if (exec) {
347
- try {
348
- exec.kill();
349
- }
350
- catch (err) {
351
- log.warn('gondolin-dispatch: exec.kill threw during teardown', {
352
- error: err.message,
353
- });
354
- }
355
- }
356
- try {
357
- await vm.close();
358
- }
359
- catch (err) {
360
- log.warn('gondolin-dispatch: vm.close threw during teardown', {
361
- error: err.message,
362
- });
363
- }
364
- if (registered) {
365
- try {
366
- registered.deregister();
367
- }
368
- catch (err) {
369
- log.warn('gondolin-dispatch: deregister threw during teardown', {
370
- error: err.message,
371
- });
372
- }
373
- }
374
- }
375
- //# sourceMappingURL=gondolin-dispatch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gondolin-dispatch.js","sourceRoot":"","sources":["../../src/agent/gondolin-dispatch.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6CAA6C;AAC7C,kFAAkF;AAClF,oFAAoF;AACpF,mFAAmF;AACnF,sEAAsE;AACtE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,gCAAgC;AAChC,mFAAmF;AACnF,mFAAmF;AACnF,yDAAyD;AACzD,EAAE;AACF,iEAAiE;AACjE,wFAAwF;AACxF,4DAA4D;AAC5D,wFAAwF;AACxF,gFAAgF;AAChF,sFAAsF;AACtF,8CAA8C;AAC9C,6EAA6E;AAC7E,qCAAqC;AAErC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAsB,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGpC,OAAO,EACL,kBAAkB,GAMnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAkB,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,wBAAwB,GAEzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,sBAAsB,GAIvB,MAAM,6BAA6B,CAAC;AAwFrC;;;;;GAKG;AACH,MAAM,gBAAgB,GAAsB,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,gBAAgB,GAAG,8DAA8D,CAAC;AAExF;;;;;;;;;;;;GAYG;AACH,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAC5D,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAEnC;;;;GAIG;AACH,SAAS,kBAAkB;IACzB,OAAO;QACL,SAAS,EAAE,oBAAoB;QAC/B,OAAO,EAAE,uBAAuB;QAChC,IAAI,EAAE,oBAAoB;KAC3B,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,IAAmB;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,MAAM,GACV,aAAa,GAAG,OAAO;QACvB,cAAc,GAAG,oBAAoB,IAAI,CAAC,SAAS,OAAO;QAC1D,SAAS,IAAI,KAAK,IAAI,CAAC,SAAS,GAAG,CAAC;IACtC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,uEAAuE;AACvE,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IACzB,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,kBAAkB;IAEV;IACA;IACA;IACA;IAJnB,YACmB,QAAkB,EAClB,QAAkC,EAClC,WAA+B,EAC/B,QAA0B;QAH1B,aAAQ,GAAR,QAAQ,CAAU;QAClB,aAAQ,GAAR,QAAQ,CAA0B;QAClC,gBAAW,GAAX,WAAW,CAAoB;QAC/B,aAAQ,GAAR,QAAQ,CAAkB;IAC1C,CAAC;IAEJ,KAAK,CAAC,QAAQ,CAAC,IAA6B;QAC1C,qEAAqE;QACrE,wEAAwE;QACxE,+EAA+E;QAC/E,4EAA4E;QAC5E,2EAA2E;QAC3E,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,eAAe,CACvE,IAAI,CAAC,WAAW,CAAC,OAAO,CACzB,CAAC;QACF,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACjE,6EAA6E;QAC7E,6EAA6E;QAC7E,+EAA+E;QAC/E,4EAA4E;QAC5E,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,GAAG;gBACZ,GAAG,OAAO,CAAC,GAAG;gBACd,KAAK,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;aACvF,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;QAElE,gFAAgF;QAChF,yEAAyE;QACzE,wBAAwB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAEvE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACpD,0EAA0E;QAC1E,8EAA8E;QAC9E,+EAA+E;QAC/E,+EAA+E;QAC/E,wEAAwE;QACxE,iEAAiE;QACjE,OAAO,IAAI,CAAC,iBAAiB,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACpF,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,iBAAiB,CAC7B,EAAY,EACZ,aAA4B,EAC5B,SAA4B,EAC5B,MAAc,EACd,IAA6B;QAE7B,IAAI,UAAU,GAAwB,IAAI,CAAC;QAC3C,IAAI,CAAC;YACH,8EAA8E;YAC9E,+EAA+E;YAC/E,+DAA+D;YAC/D,UAAU,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;YAC7D,0EAA0E;YAC1E,yEAAyE;YACzE,yEAAyE;YACzE,4EAA4E;YAC5E,wEAAwE;YACxE,MAAM,IAAI,CAAC,mBAAmB,CAC5B,EAAE,EACF,CAAC,kBAAkB,EAAE,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,EAC3E,IAAI,CAAC,OAAO,CACb,CAAC;YACF,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,6EAA6E;YAC7E,6EAA6E;YAC7E,sEAAsE;YACtE,MAAM,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YAC7C,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,cAAc,CAC1B,IAA6B,EAC7B,cAAsC;QAEtC,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;QAC/C,MAAM,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACrD,OAAO,sBAAsB,CAAC,IAAI,CAAC,WAAW,CAAC,SAAyB,EAAE;YACxE,WAAW;YACX,UAAU;YACV,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;YACzC,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,mBAAmB,CAC/B,EAAY,EACZ,KAA+B,EAC/B,OAAe;QAEf,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;gBACnB,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBAC5B,OAAO;gBACP,SAAS,EAAE,gBAAgB;aAC5B,CAAC,CAAC;YACH,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IAED,yFAAyF;IACjF,oBAAoB,CAC1B,IAA6B,EAC7B,SAAuC,EACvC,OAAkB;QAElB,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS;YAClC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACxB,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC5B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC;YACjC,SAAS;YACT,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,4EAA4E;YAC5E,wEAAwE;YACxE,yEAAyE;YACzE,uEAAuE;YACvE,8EAA8E;YAC9E,8EAA8E;YAC9E,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,eAAe;YACjD,YAAY,EAAE,GAAG,kBAAkB,GAAG,IAAI,CAAC,UAAU,EAAE;YACvD,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC;IACJ,CAAC;IAED,+EAA+E;IACvE,KAAK,CAAC,qBAAqB,CAAC,OAAsB;QACxD,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC5B,OAAO;YACP,UAAU,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU;YACvC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,SAAyB;SACtD,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,WAAW,CACjB,EAAY,EACZ,IAA6B,EAC7B,MAAc,EACd,cAAsC;QAEtC,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,CAAC,GAAG,gBAAgB,CAAC;YAC9B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC;YACtD,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,cAAc,CACpB,IAA6B,EAC7B,MAAc,EACd,cAAsC;QAEtC,OAAO;YACL,qEAAqE;YACrE,6EAA6E;YAC7E,0CAA0C;YAC1C,IAAI,EAAE,gBAAgB;YACtB,wEAAwE;YACxE,4EAA4E;YAC5E,+EAA+E;YAC/E,gEAAgE;YAChE,0DAA0D;YAC1D,iBAAiB,EAAE,oBAAoB;YACvC,gBAAgB,EAAE,MAAM;YACxB,kBAAkB,EAAE,IAAI,CAAC,QAAQ;YACjC,oBAAoB,EAAE,IAAI,CAAC,UAAU;YACrC,qBAAqB,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;YACvD,GAAG,wBAAwB,CAAC,IAAI,CAAC,UAAU,CAAC;YAC5C,6EAA6E;YAC7E,GAAG,cAAc;SAClB,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACK,eAAe,CAAC,IAAY,EAAE,IAAgB;QACpD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACvC,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,CAAC,CAAC;YACd,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,sCAAsC,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kFAAkF;IAC1E,WAAW,CACjB,EAAY,EACZ,IAAY,EACZ,UAAwB,EACxB,MAAc,EACd,SAA4B;QAE5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,OAAO;YACL,EAAE;YACF,IAAI;YACJ,MAAM;YACN,SAAS;YACT,QAAQ,EAAE,KAAK,IAAI,EAAE;gBACnB,IAAI,QAAQ;oBAAE,OAAO;gBACrB,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;YAC/C,CAAC;SACF,CAAC;IACJ,CAAC;CACF;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,gBAAgB,CAC7B,EAAY,EACZ,IAAmB,EACnB,UAA+B;IAE/B,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,oDAAoD,EAAE;gBAC7D,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,mDAAmD,EAAE;YAC5D,KAAK,EAAG,GAAa,CAAC,OAAO;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,UAAU,CAAC,UAAU,EAAE,CAAC;QAC1B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,qDAAqD,EAAE;gBAC9D,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -1,124 +0,0 @@
1
- // GondolinVmClient — concrete VM-substrate adapter over `@earendil-works/gondolin`.
2
- //
3
- // Implements the `vm-port.ts` contract. Thin by design: `createVm` → `VM.create`
4
- // (host mounts become `RealFSProvider`/`ReadonlyProvider` VFS entries), the
5
- // handle's `exec` → `vm.exec` (piped stdio + an `AbortController` standing in
6
- // for the VM port's `kill()`), `close` → `vm.close`, and `listSessions`/`gc`
7
- // → Gondolin's session registry. No domain imports (hexagonal `adapters↛inward`).
8
- //
9
- // Phase 0: added but not yet wired into the runner/reconciler — that is Phase 1+.
10
- import { VM, RealFSProvider, ReadonlyProvider, listSessions as gondolinListSessions, gcSessions, } from '@earendil-works/gondolin';
11
- import { VmProcessRegistry } from './vm-process-registry.js';
12
- class GondolinVmHandle {
13
- vm;
14
- onClose;
15
- /**
16
- * `onClose` deregisters this VM from the client's process registry after a
17
- * clean `close()` (which has already torn down qemu). Defaults to a no-op so
18
- * the handle can be constructed without a registry in tests.
19
- */
20
- constructor(vm, onClose = () => undefined) {
21
- this.vm = vm;
22
- this.onClose = onClose;
23
- }
24
- get id() {
25
- return this.vm.id;
26
- }
27
- exec(opts) {
28
- // Gondolin has no `proc.kill()`; aborting the signal passed to `exec` is the
29
- // teardown path, so the handle owns the controller.
30
- const ac = new AbortController();
31
- const proc = this.vm.exec(opts.command, {
32
- cwd: opts.workdir ?? undefined,
33
- env: opts.env,
34
- stdin: true,
35
- stdout: 'pipe',
36
- stderr: 'pipe',
37
- signal: ac.signal,
38
- });
39
- const stdout = proc.stdout;
40
- const stderr = proc.stderr;
41
- if (!stdout || !stderr) {
42
- throw new Error('gondolin exec did not expose piped stdout/stderr');
43
- }
44
- let killed = false;
45
- return {
46
- stdin: {
47
- write: (chunk) => proc.write(chunk),
48
- end: () => proc.end(),
49
- },
50
- stdout,
51
- stderr,
52
- pid: this.vm.getHostPid() ?? undefined,
53
- exit: proc.result.then((r) => ({ code: r.exitCode, signal: r.signal ?? null })),
54
- kill: () => {
55
- if (killed)
56
- return;
57
- killed = true;
58
- try {
59
- ac.abort();
60
- }
61
- catch {
62
- // idempotent — already aborted / process gone
63
- }
64
- },
65
- };
66
- }
67
- async close() {
68
- // Deregister only after a clean close. If `close()` throws, the VM stays
69
- // tracked so the force-quit backstop (`killAllVms`) can still SIGKILL its
70
- // backing qemu — a teardown that failed must not leave an orphan.
71
- await this.vm.close();
72
- this.onClose();
73
- }
74
- }
75
- export class GondolinVmClient {
76
- // Tracks the backing host (qemu) process of every live VM so a forced exit can
77
- // SIGKILL them before `process.exit` (issue 152). Each qemu is a direct child
78
- // of this in-process orchestrator; the session registry only knows our own
79
- // pid, so this is the sole reliable handle on the backing process.
80
- procRegistry;
81
- constructor(opts = {}) {
82
- this.procRegistry = new VmProcessRegistry(opts);
83
- }
84
- async createVm(opts) {
85
- const mounts = {};
86
- for (const m of opts.mounts) {
87
- const provider = new RealFSProvider(m.host);
88
- mounts[m.guest] = m.readonly ? new ReadonlyProvider(provider) : provider;
89
- }
90
- const options = {
91
- sandbox: { imagePath: opts.imagePath },
92
- cpus: opts.cpus,
93
- memory: `${opts.memMib}M`,
94
- env: opts.env,
95
- vfs: { mounts },
96
- httpHooks: opts.httpHooks,
97
- tcp: opts.tcp,
98
- dns: opts.dns,
99
- allowWebSockets: opts.allowWebSockets,
100
- sessionLabel: opts.sessionLabel,
101
- };
102
- const vm = await VM.create(options);
103
- const deregister = this.procRegistry.track(vm);
104
- return new GondolinVmHandle(vm, deregister);
105
- }
106
- /** @see VmClient.killAllVms — synchronous, best-effort qemu reap on forced exit. */
107
- killAllVms() {
108
- return this.procRegistry.killAll();
109
- }
110
- async listSessions() {
111
- const sessions = await gondolinListSessions();
112
- return sessions.map((s) => ({
113
- id: s.id,
114
- pid: s.pid,
115
- label: s.label,
116
- alive: s.alive,
117
- createdAt: s.createdAt,
118
- }));
119
- }
120
- async gc() {
121
- return gcSessions();
122
- }
123
- }
124
- //# sourceMappingURL=gondolin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"gondolin.js","sourceRoot":"","sources":["../../src/agent/gondolin.ts"],"names":[],"mappings":"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"}
@@ -1,134 +0,0 @@
1
- // Pure decisions extracted from `runAttempt` / its cleanup closure (issues 62, 103).
2
- // The runner remains the imperative shell that drives ports (the Gondolin VM, bridge,
3
- // tracker, typed actions); each helper here takes a snapshot of shell state and
4
- // returns the next decision so branches can be unit tested without spinning
5
- // up a VM or a workspace. Everything in this module is deterministic and
6
- // side-effect free.
7
- /**
8
- * Collapse the three failure channels into one AttemptOutcome.
9
- * Precedence: agentFailure > non-routed terminal-action failure > success.
10
- * The non-routed action failure case fronts a `state action failed: ` prefix
11
- * so the orchestrator (and any downstream `reason`-keyed dashboard logic)
12
- * can tell apart "the agent itself failed" from "the post-agent push/PR
13
- * step failed". Silently treating a failed push as success was the prior
14
- * bug this contract closes.
15
- */
16
- export function decideAttemptOutcome(input) {
17
- if (input.agentFailure !== null) {
18
- return {
19
- ok: false,
20
- reason: input.agentFailure,
21
- threadId: input.sessionId,
22
- turnsCompleted: input.turnsCompleted,
23
- };
24
- }
25
- if (input.nonRoutedActionFailureReason !== null) {
26
- return {
27
- ok: false,
28
- reason: `state action failed: ${input.nonRoutedActionFailureReason}`,
29
- threadId: input.sessionId,
30
- turnsCompleted: input.turnsCompleted,
31
- };
32
- }
33
- return {
34
- ok: true,
35
- reason: input.lastReason,
36
- threadId: input.sessionId,
37
- turnsCompleted: input.turnsCompleted,
38
- };
39
- }
40
- /**
41
- * Pick which prompt template to render for the next iteration. A pending
42
- * steering reply trumps everything (the human is in the loop), then the
43
- * first-turn full prompt, then the bare continuation prompt for later
44
- * autonomous turns.
45
- */
46
- export function selectPromptKind(input) {
47
- if (input.pendingSteering)
48
- return 'steering';
49
- if (input.firstTurn)
50
- return 'initial';
51
- return 'continuation';
52
- }
53
- /**
54
- * Classify the outcome of a single `runPrompt`. `end_turn` is the happy path.
55
- * Anything else is a failure UNLESS the agent has called `symphony.transition`
56
- * (which can race with the adapter's reply): `transitioned` overrides because
57
- * the work is genuinely done and reconcile may have tripped the cancel signal
58
- * mid-flight, masking the real reason.
59
- */
60
- export function classifyTurnOutcome(input) {
61
- if (input.outcomeReason === 'end_turn')
62
- return { kind: 'success' };
63
- if (input.transitioned)
64
- return { kind: 'agent_transitioned' };
65
- return {
66
- kind: 'agent_failure',
67
- agentFailure: `agent turn ${input.outcomeReason}: ${input.outcomeMessage}`,
68
- reason: input.outcomeReason,
69
- };
70
- }
71
- /**
72
- * Decide whether the autonomous loop should run another iteration after a
73
- * successful `end_turn`. The three break conditions, in order: the tracker
74
- * lost the issue (file deleted out from under us), the issue moved to an
75
- * inactive state (terminal, holding, or routed elsewhere), or the per-state
76
- * `max_turns` budget is spent.
77
- */
78
- export function decideTurnContinuation(input) {
79
- if (input.refreshedIssue === null)
80
- return { kind: 'break', reason: 'issue_no_longer_present' };
81
- if (!input.activeStates.has(input.refreshedIssue.state.toLowerCase())) {
82
- return { kind: 'break', reason: 'issue_no_longer_active' };
83
- }
84
- if (input.autonomousTurns >= input.maxTurns) {
85
- return { kind: 'break', reason: 'max_turns_reached' };
86
- }
87
- return { kind: 'continue' };
88
- }
89
- /**
90
- * Map a `RunningEntry` snapshot + optional staged SYMPHONY_* env into the
91
- * `ActionContext` the actions executor consumes. Mirrors the prior inline
92
- * fallback chain in `buildActionContext` so a Done state reads `$branch` from
93
- * the action template namespace (the staged SYMPHONY_* env feeds the fallbacks).
94
- *
95
- * Lifting the ternary fallbacks here drops `buildActionContext`'s
96
- * complexity from 14 to 1 (single pass-through call), letting the shell
97
- * stay under the imperative-shell budget.
98
- */
99
- /**
100
- * Compute the VM boot env from the `forward_env` list, dropping `omitVar` when
101
- * set. `omitVar` lets a caller exclude a single var from the forwarded set; the
102
- * runner now strips every credential-bearing var uniformly via
103
- * `stripCredentialEnv` (the guest holds only a placeholder Gondolin substitutes
104
- * at egress), so it passes `undefined` here. `readEnv` is injected so this stays
105
- * deterministic and unit-testable.
106
- */
107
- export function computeForwardedEnv(forwardList, omitVar, readEnv) {
108
- const env = {};
109
- for (const k of forwardList) {
110
- if (k === omitVar)
111
- continue;
112
- const v = readEnv(k);
113
- if (v && v.length > 0)
114
- env[k] = v;
115
- }
116
- return env;
117
- }
118
- export function deriveActionContext(input) {
119
- const trimmedTitle = input.issueTitle.trim();
120
- const defaultPrTitle = trimmedTitle.length > 0 ? `${input.issueId}: ${trimmedTitle}` : input.issueId;
121
- const repoEnv = input.repoEnv;
122
- return {
123
- identifier: input.identifier,
124
- workspace: input.workspacePath,
125
- branch: input.extraEnv?.SYMPHONY_BRANCH ?? `agent/${input.identifier}`,
126
- base_branch: input.extraEnv?.SYMPHONY_BASE_BRANCH ?? 'main',
127
- issue_title: input.issueTitle,
128
- issue_body: input.issueDescription ?? '',
129
- repo: repoEnv && repoEnv.length > 0 ? repoEnv : null,
130
- pr_title: input.extraEnv?.SYMPHONY_PR_TITLE ?? defaultPrTitle,
131
- pr_body_file: input.extraEnv?.SYMPHONY_PR_BODY_FILE ?? '',
132
- };
133
- }
134
- //# sourceMappingURL=runner-decisions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner-decisions.js","sourceRoot":"","sources":["../../src/agent/runner-decisions.ts"],"names":[],"mappings":"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"}