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,158 @@
1
+ // FCIS rewrite — pure-ish bring-up helpers for the Gondolin dispatch adapter
2
+ // (split out of gondolin-dispatch.ts to keep that file under the shell line budget).
3
+ // Ports the reference src/agent/gondolin-dispatch.ts free functions verbatim. Shell
4
+ // rule: imports from src/types/** ONLY (plus the real Gondolin SDK type surface).
5
+ import { Buffer } from 'node:buffer';
6
+ import { readdir } from 'node:fs/promises';
7
+ /**
8
+ * Build the guest→host control-plane tunnel from the plan's tunnel decision. When the
9
+ * tcp.hosts entry is present, ACP (ws://symphony-mcp:7001/acp) and MCP HTTP share this
10
+ * ONE entry; synthetic per-host DNS resolves the mapped name. When empty (MCP disabled or
11
+ * reached via an explicit URL), no tunnel is added — the guest reaches the host directly.
12
+ */
13
+ export function buildTunnel(plan) {
14
+ const entry = plan.tunnel.tcpHostEntry;
15
+ if (!entry || Object.keys(entry).length === 0)
16
+ return {};
17
+ return {
18
+ tcp: { hosts: entry },
19
+ dns: { mode: 'synthetic', syntheticHostMapping: 'per-host' },
20
+ };
21
+ }
22
+ /**
23
+ * POSIX single-quote-safe shell quoter. Wraps the value in single quotes and escapes any
24
+ * embedded single quote with the canonical `'\''` close-escape-reopen trick. Use this for
25
+ * EVERY host-controlled value interpolated into a `/bin/sh -c '…'` script — a configured
26
+ * guest path (gondolin.guest_agent_path) or adapter name containing a `'` would otherwise
27
+ * break out of the quoting and inject arbitrary commands into the guest shell.
28
+ */
29
+ export function shQuote(value) {
30
+ return `'${value.replace(/'/g, `'\\''`)}'`;
31
+ }
32
+ /**
33
+ * The in-guest write command for one guest file. The content is base64-encoded host-side
34
+ * and decoded in-guest, so arbitrary JSON (quotes, newlines, `$`) can never break out of
35
+ * the shell — no heredoc/echo injection surface. `mkdir -p` the parent, decode into place,
36
+ * then chmod. POSIX-portable (/bin/sh, base64 -d). The guest path + dir are shell-quoted
37
+ * (shQuote) so a path containing a `'` cannot break out of the single quotes and inject.
38
+ */
39
+ export function writeFileCommand(file) {
40
+ const b64 = Buffer.from(file.content, 'utf8').toString('base64');
41
+ const dir = posixDirname(file.guestPath);
42
+ const mode = file.mode.toString(8);
43
+ const script = `mkdir -p ${shQuote(dir)} && ` +
44
+ `printf %s '${b64}' | base64 -d > ${shQuote(file.guestPath)} && ` +
45
+ `chmod ${mode} ${shQuote(file.guestPath)}`;
46
+ return ['/bin/sh', '-c', script];
47
+ }
48
+ /** POSIX dirname for an absolute guest path (always `/`-separated). */
49
+ function posixDirname(p) {
50
+ const idx = p.lastIndexOf('/');
51
+ if (idx <= 0)
52
+ return '/';
53
+ return p.slice(0, idx);
54
+ }
55
+ /**
56
+ * Run a one-shot guest exec to completion, bounded by an OWN `kill()` timer, capturing
57
+ * stdout/stderr via non-blocking `'data'` taps and keying completion off `exec.exit` —
58
+ * NEVER on the streams reaching EOF. Load-bearing: the live VmHandle.exec does not honor
59
+ * `opts.timeoutMs`, so a probe that awaited stdout `'end'` would hang forever on a
60
+ * half-open guest pipe (the Node pipe-EOF gotcha). Taps attach BEFORE `stdin.end()` so no
61
+ * early chunk is missed.
62
+ */
63
+ export async function runBoundedExec(exec, timeoutMs) {
64
+ const stdoutTap = tapStream(exec.stdout);
65
+ const stderrTap = tapStream(exec.stderr);
66
+ exec.stdin.end();
67
+ let timedOut = false;
68
+ const timer = setTimeout(() => {
69
+ timedOut = true;
70
+ try {
71
+ exec.kill();
72
+ }
73
+ catch {
74
+ /* idempotent — already aborted / process gone */
75
+ }
76
+ }, timeoutMs);
77
+ let code;
78
+ try {
79
+ ({ code } = await exec.exit);
80
+ }
81
+ finally {
82
+ clearTimeout(timer);
83
+ }
84
+ return { code, stdout: stdoutTap.read(), stderr: stderrTap.read(), timedOut };
85
+ }
86
+ /**
87
+ * Non-blocking accumulator for a guest exec's stdout/stderr. Attaches a `'data'` listener
88
+ * that appends each chunk to a buffer the caller reads AFTER `exec.exit` resolves — it
89
+ * NEVER awaits the stream reaching EOF (the Node pipe-EOF gotcha).
90
+ */
91
+ function tapStream(stream) {
92
+ let out = '';
93
+ stream.setEncoding('utf8');
94
+ stream.on('data', (chunk) => {
95
+ out += chunk;
96
+ });
97
+ return { read: () => out };
98
+ }
99
+ // NOTE (§4a): the BYO-probe exit-code→message decision moved to core
100
+ // `vm-plan.ts:byoProbeFailureMessage` and is INJECTED into the GondolinDispatcher
101
+ // (the shell runs the probe exec, core maps the code to the operator message).
102
+ /**
103
+ * Run the in-guest `mise install` step (issue 209) — provision node + the agent CLIs
104
+ * (staged SYSTEM config) + any project toolchains (the workspace mise.toml), bounded
105
+ * by an OWN `kill()` timer. Best-effort reads the workspace dir and logs whether a
106
+ * project config was detected (via the injected pure `detectProjectConfig` decider) so
107
+ * the operator can see the project contributed toolchains. Returns the bounded result;
108
+ * the caller throws a typed ByoContractError on a non-zero exit.
109
+ */
110
+ export async function runMiseInstall(vm, opts, detectProjectConfig, log, timeoutMs) {
111
+ let hasProject = false;
112
+ try {
113
+ hasProject = detectProjectConfig(await readdir(opts.workdir));
114
+ }
115
+ catch {
116
+ /* best-effort: an unreadable workspace just logs no project config */
117
+ }
118
+ log.emit('info', 'gondolin-dispatch: mise install', { workdir: opts.workdir, project_config: hasProject });
119
+ return runBoundedExec(vm.exec({ command: opts.command, workdir: opts.workdir, env: opts.env, timeoutMs }), timeoutMs);
120
+ }
121
+ /**
122
+ * Idempotent, error-tolerant teardown: kill the exec, close the VM, deregister the secret
123
+ * manager. Each step is independently guarded so one failure does not strand the others.
124
+ * `exec` is null when teardown runs from a bring-up failure that aborted BEFORE the launch
125
+ * exec was created; `registered` is null when the secret manager never got registered —
126
+ * both are skipped so the partial-bring-up cleanup is safe at any failure point.
127
+ */
128
+ export async function teardownDispatch(vm, exec, registered, log) {
129
+ if (exec) {
130
+ try {
131
+ exec.kill();
132
+ }
133
+ catch (err) {
134
+ log.emit('warn', 'gondolin-dispatch: exec.kill threw during teardown', {
135
+ error: err.message,
136
+ });
137
+ }
138
+ }
139
+ try {
140
+ await vm.close();
141
+ }
142
+ catch (err) {
143
+ log.emit('warn', 'gondolin-dispatch: vm.close threw during teardown', {
144
+ error: err.message,
145
+ });
146
+ }
147
+ if (registered) {
148
+ try {
149
+ registered.deregister();
150
+ }
151
+ catch (err) {
152
+ log.emit('warn', 'gondolin-dispatch: deregister threw during teardown', {
153
+ error: err.message,
154
+ });
155
+ }
156
+ }
157
+ }
158
+ //# sourceMappingURL=gondolin-dispatch-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin-dispatch-helpers.js","sourceRoot":"","sources":["../../../../src/shell/adapter/gondolin-dispatch-helpers.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,qFAAqF;AACrF,oFAAoF;AACpF,kFAAkF;AAElF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAO3C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;IACvC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACzD,OAAO;QACL,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAgB;QACnC,GAAG,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,oBAAoB,EAAE,UAAU,EAAgB;KAC3E,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAA0D;IACzF,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,YAAY,OAAO,CAAC,GAAG,CAAC,MAAM;QAC9B,cAAc,GAAG,mBAAmB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM;QACjE,SAAS,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;IAC7C,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;AAWD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY,EAAE,SAAiB;IAClE,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC;YACH,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;IACH,CAAC,EAAE,SAAS,CAAC,CAAC;IACd,IAAI,IAAmB,CAAC;IACxB,IAAI,CAAC;QACH,CAAC,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,SAAS,SAAS,CAAC,MAAgB;IACjC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;QAClC,GAAG,IAAI,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AAC7B,CAAC;AAED,qEAAqE;AACrE,kFAAkF;AAClF,+EAA+E;AAE/E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,EAAY,EACZ,IAAyE,EACzE,mBAA4D,EAC5D,GAAY,EACZ,SAAiB;IAEjB,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,mBAAmB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,iCAAiC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC,CAAC;IAC3G,OAAO,cAAc,CACnB,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,EACnF,SAAS,CACV,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAY,EACZ,IAAmB,EACnB,UAA+B,EAC/B,GAAY;IAEZ,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,MAAM,EAAE,oDAAoD,EAAE;gBACrE,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,MAAM,EAAE,mDAAmD,EAAE;YACpE,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,MAAM,EAAE,qDAAqD,EAAE;gBACtE,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,385 @@
1
+ // FCIS rewrite — per-dispatch Gondolin bring-up adapter (kind: adapter).
2
+ //
3
+ // The IMPERATIVE bring-up + teardown sequence for ONE dispatch, executing the
4
+ // pure `VmPlan` the core assembled (src/core/runner/vm-plan.ts: buildVmPlan):
5
+ // 1. the host hands in the per-dispatch { httpHooks, secretManager } it built from
6
+ // the ONE AdapterCredentialSpec (live-token-keyed: the codex chatgpt-backend
7
+ // route swap is active). The placeholder env is already baked into the plan's
8
+ // guestFiles + launchEnv by core; the host keeps the secretManager (→ registry)
9
+ // + httpHooks (→ createVm).
10
+ // 2. register the per-VM secretManager with the injected registry BEFORE the agent
11
+ // launches (the placeholder's real value must be present before the first egress).
12
+ // 3. createVm with the plan's mounts/env + the built httpHooks/tcp/dns (the
13
+ // control-plane tunnel) + allowWebSockets.
14
+ // 4. materialize the plan's guest file set (launcher + gitconfig + fake creds + effort
15
+ // files) via the base64-pipe write-exec, with a /tmp fallback for the launcher when
16
+ // a readonly-rootfs BYO image fails the primary write.
17
+ // 5. probe the BYO image (resolve absolute node + adapter paths, assert Node≥21 /
18
+ // global WebSocket, confirm the launcher materialized) — fail FAST with a typed
19
+ // ByoContractError instead of an opaque post-launch ENOENT.
20
+ // 6. exec the agent ([resolvedNode, launcherPath]) with the plan's launchEnv; stdin
21
+ // end()ed immediately (ACP rides the /acp WebSocket, not stdio); stderr tapped.
22
+ // 7. idempotent, error-tolerant teardown: kill the exec, close the VM, deregister.
23
+ //
24
+ // Ports the reference src/agent/gondolin-dispatch.ts + launcher-asset.ts (read-only).
25
+ // THIN by design: every routing/precedence/env/argv decision already lives in core
26
+ // (buildVmPlan); this file only EXECUTES. Shell rule: imports from src/types/** ONLY
27
+ // (plus the real Gondolin SDK). NodeNext ESM, .js extensions on relative imports.
28
+ import os from 'node:os';
29
+ import { buildTunnel, writeFileCommand, runBoundedExec, runMiseInstall, teardownDispatch, } from './gondolin-dispatch-helpers.js';
30
+ /**
31
+ * A bring-your-own-image contract violation surfaced by the pre-launch probe (missing
32
+ * node ≥21 / global WebSocket, missing adapter CLI, or the launcher failed to
33
+ * materialize). Thrown BEFORE the agent launch so the dispatch fails fast with a precise,
34
+ * operator-facing message instead of an opaque ENOENT / never-dials-back failure. A
35
+ * distinct type so the classifier/teardown can recognise it.
36
+ */
37
+ class ByoContractError extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = 'ByoContractError';
41
+ }
42
+ }
43
+ // ─── Fixed constants (ported verbatim from the reference) ──────────────────────
44
+ /** Always-tmpfs fallback the launcher is re-staged under when the primary write fails. */
45
+ const VM_AGENT_TMP_FALLBACK_PATH = '/tmp/symphony/vm-agent.mjs';
46
+ // TODO(§4b): byte-identical twins of core `vm-plan.ts:VM_AGENT_LAUNCHER_MODE` /
47
+ // `GUEST_AGENT_PATH`. The shell may not import core, and the only seam here is the
48
+ // GondolinDispatcher constructor — threading two injected scalars for the /tmp
49
+ // FALLBACK re-stage + the probe PATH is more churn than the "low, don't force it"
50
+ // item warrants (the primary launcher already carries `mode` from the core plan).
51
+ // Left as a documented twin; inject via the dispatcher ctor when one of them changes.
52
+ /** Non-secret mode for the re-staged launcher under the /tmp fallback. */
53
+ const VM_AGENT_LAUNCHER_MODE = 0o644;
54
+ /**
55
+ * Launch/probe PATH. `vm.exec` runs WITHOUT a login shell, so the profile PATH does not
56
+ * apply. The mise shims dir leads (issue 209) so shim-resolved children pick up the
57
+ * project's tools; the `mise` binary + any baked node sit under /usr/local/bin. A
58
+ * non-existent shims dir (not yet installed) is harmlessly skipped.
59
+ * BYTE-IDENTICAL twin of core `vm-plan.ts:GUEST_AGENT_PATH` (the shell may not import core).
60
+ */
61
+ const GUEST_AGENT_PATH = '/opt/symphony/mise-data/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
62
+ /** Bound on each guest write-exec (a tiny mkdir+decode+chmod; never hangs). */
63
+ const STAGE_TIMEOUT_MS = 15_000;
64
+ /** Bound on the pre-launch BYO probe exec (a tiny `command -v` chain; never hangs). */
65
+ const PROBE_TIMEOUT_MS = 15_000;
66
+ /**
67
+ * Bound on the in-guest `mise install` exec (issue 209). Generous — a COLD cache
68
+ * downloads node + the agent CLIs + any project toolchains; the persistent download cache
69
+ * (issue 222) lets a warm install skip the re-download (the slow part), though the
70
+ * extract + chmod onto the ephemeral rootfs still runs each dispatch.
71
+ */
72
+ const MISE_INSTALL_TIMEOUT_MS = 600_000;
73
+ // ─── The dispatcher ────────────────────────────────────────────────────────────
74
+ /**
75
+ * Orchestrates a single Gondolin dispatch — the ONE VM bring-up path. Inject the
76
+ * VM port, the host secret registry, the injected pure/IO deciders (the
77
+ * credential-mount guard, the symlink realpath resolver, the BYO-probe
78
+ * failure-message mapper), and a log sink; `dispatch()` executes the core-built
79
+ * plan (stage guest files incl. the launcher, BYO probe, launch the in-VM agent)
80
+ * with the per-dispatch live-token-keyed egress hooks the host hands in, and
81
+ * returns an idempotent teardown handle.
82
+ */
83
+ export class GondolinDispatcher {
84
+ vmClient;
85
+ registry;
86
+ assertNoCredentialMounts;
87
+ resolveMountRealpath;
88
+ byoProbeFailureMessage;
89
+ byoProbeScript;
90
+ miseInstallFailureMessage;
91
+ hasProjectMiseConfig;
92
+ log;
93
+ constructor(vmClient, registry, assertNoCredentialMounts, resolveMountRealpath, byoProbeFailureMessage, byoProbeScript, miseInstallFailureMessage, hasProjectMiseConfig, log) {
94
+ this.vmClient = vmClient;
95
+ this.registry = registry;
96
+ this.assertNoCredentialMounts = assertNoCredentialMounts;
97
+ this.resolveMountRealpath = resolveMountRealpath;
98
+ this.byoProbeFailureMessage = byoProbeFailureMessage;
99
+ this.byoProbeScript = byoProbeScript;
100
+ this.miseInstallFailureMessage = miseInstallFailureMessage;
101
+ this.hasProjectMiseConfig = hasProjectMiseConfig;
102
+ this.log = log;
103
+ }
104
+ async dispatch(opts) {
105
+ // SECURITY (host-only-refresh invariant teeth): HARD-FAIL before createVm if
106
+ // any plan mount overlaps a credential directory or is the home-dir root. The
107
+ // pure denylist check is injected (core/vm-guards.ts:assertNoCredentialMounts);
108
+ // a throw aborts the dispatch before any VM exists. vm-plan.ts documents this
109
+ // guard as the shell's job — this is its sole runtime call site.
110
+ //
111
+ // The core guard is LEXICAL-only, so a symlink whose lexical path is benign but
112
+ // whose target overlaps a credential dir would slip past. We `realpath` every
113
+ // mount host path (IO) and feed BOTH the lexical AND the resolved form to the
114
+ // guard, closing the symlink bypass (codex HIGH).
115
+ await this.assertMountsAllowed(opts.plan.mounts);
116
+ // The per-dispatch egress hooks the host built from the ONE spec it threads
117
+ // everywhere (live-token-keyed so the codex chatgpt-backend route swap is
118
+ // active). httpHooks → createVm; secretManager → the registry. The placeholder
119
+ // bearer is already baked into the plan's guestFiles + launchEnv by core.
120
+ const { httpHooks, secretManager } = opts.egress;
121
+ const { tcp, dns } = buildTunnel(opts.plan);
122
+ const vm = await this.vmClient.createVm({
123
+ imagePath: opts.plan.imagePath,
124
+ cpus: opts.plan.cpus,
125
+ memMib: opts.plan.memMib,
126
+ // Grow the guest rootfs so the ephemeral mise install fits (issue 222).
127
+ rootfsSize: opts.plan.rootfsSize,
128
+ mounts: opts.plan.mounts,
129
+ env: opts.plan.env,
130
+ httpHooks,
131
+ tcp,
132
+ dns,
133
+ allowWebSockets: opts.plan.allowWebSockets,
134
+ sessionLabel: opts.plan.sessionLabel,
135
+ workdir: opts.workdir,
136
+ });
137
+ // The host registers the ACP dispatch context (vmId → issue/workspace + MCP
138
+ // servers) the moment the VM exists, BEFORE the agent dials back. Inside the
139
+ // try so a thrown hook still tears the VM down (it has not registered yet).
140
+ // Once the VM exists every later step can throw before the handle (the only
141
+ // teardown affordance) returns — guard the whole bring-up: on any failure close the
142
+ // VM + deregister (if registered), then rethrow.
143
+ return this.bringUpOrTeardown(vm, secretManager, opts);
144
+ }
145
+ /**
146
+ * Resolve the symlink-canonical form of every mount host path (IO) and run the
147
+ * injected core guard over BOTH the lexical AND the resolved mount set. A throw
148
+ * from either aborts the dispatch before any VM exists.
149
+ */
150
+ async assertMountsAllowed(mounts) {
151
+ const homeDir = os.homedir();
152
+ const resolved = await Promise.all(mounts.map(async (m) => ({ ...m, host: await this.resolveMountRealpath(m.host) })));
153
+ // One guard call over lexical ∪ resolved so a symlinked credential mount is
154
+ // rejected even when its lexical path is benign. (The core guard is idempotent
155
+ // over duplicates — a non-symlink path appears in both lists identically.)
156
+ this.assertNoCredentialMounts([...mounts, ...resolved], { homeDir });
157
+ }
158
+ /**
159
+ * Register the secret manager, stage the plan's guest files, probe, and launch —
160
+ * tearing the VM down (and deregistering) on any failure so a post-createVm throw can
161
+ * never leak the VM handle the caller never received.
162
+ */
163
+ async bringUpOrTeardown(vm, secretManager, opts) {
164
+ let registered = null;
165
+ try {
166
+ // Register the ACP dispatch context (vmId → issue/workspace + MCP servers) the
167
+ // moment the VM exists, BEFORE the agent dials back the /acp WebSocket. Inside
168
+ // the try so a thrown registration still tears the VM down.
169
+ opts.onVmCreated?.(vm.id);
170
+ // Seed + register BEFORE launch so the placeholder's real value is present before
171
+ // the first egress. AWAIT it before exec.
172
+ registered = await this.registry.register({
173
+ manager: secretManager,
174
+ secretName: opts.egress.secretName,
175
+ adapterId: opts.egress.adapterId,
176
+ });
177
+ // Stage every plan guest file (launcher FIRST so its landed path drives the probe
178
+ // + the exec), with a /tmp fallback for the launcher on a readonly-rootfs image.
179
+ const launcherGuestPath = await this.stageGuestFiles(vm, opts);
180
+ // mise toolchain provisioning (issue 209/222): AFTER staging the SYSTEM config,
181
+ // BEFORE the probe resolves node + the adapter shim. First prep the persistent
182
+ // download cache (point mise's downloads at the bind mount), then install the merged
183
+ // SYSTEM (node + the agent CLIs) + project (the workspace mise.toml) tool set onto
184
+ // the chmod-capable guest rootfs.
185
+ await this.runMisePrepStep(vm, opts);
186
+ await this.runMiseInstallStep(vm, opts);
187
+ // Probe the BYO layout AFTER staging+install, BEFORE launch — fail fast with a typed error.
188
+ const probe = await this.probeGuest(vm, opts, launcherGuestPath);
189
+ // Launch with the absolute node + launcher paths the probe resolved.
190
+ const exec = this.launchAgent(vm, opts, probe, launcherGuestPath);
191
+ return this.buildHandle(vm, exec, registered);
192
+ }
193
+ catch (err) {
194
+ await teardownDispatch(vm, null, registered, this.log);
195
+ throw err;
196
+ }
197
+ }
198
+ /**
199
+ * Materialize the plan's ordered guest file set via the base64-pipe write-exec,
200
+ * returning the guest path the launcher (plan.guestFiles[0]) actually landed at. The
201
+ * launcher rides a verify-after-write /tmp fallback (a readonly-rootfs BYO image fails
202
+ * the primary write); every other file is awaited so it exists before launch.
203
+ */
204
+ async stageGuestFiles(vm, opts) {
205
+ const [launcher, ...rest] = opts.plan.guestFiles;
206
+ if (!launcher) {
207
+ throw new ByoContractError('VmPlan.guestFiles is empty: no in-VM launcher to stage.');
208
+ }
209
+ const launcherGuestPath = await this.stageLauncher(vm, launcher, opts.workdir);
210
+ for (const f of rest) {
211
+ await this.writeGuestFile(vm, f, opts.workdir);
212
+ }
213
+ return launcherGuestPath;
214
+ }
215
+ /**
216
+ * Stage the launcher with a verify-after-write /tmp fallback. Gondolin's default rootfs
217
+ * is `cow` (writable per-VM overlay) so the primary write normally lands; a BYO image
218
+ * with a readonly-rootfs manifest fails it — detected via the exec's non-zero exit —
219
+ * so we retry under the always-tmpfs /tmp and return THAT path, keeping the write
220
+ * target and the exec arg in lockstep.
221
+ */
222
+ async stageLauncher(vm, launcher, workdir) {
223
+ const primary = await this.writeGuestFile(vm, launcher, workdir);
224
+ if (primary.code === 0)
225
+ return launcher.guestPath;
226
+ this.log.emit('warn', 'gondolin-dispatch: launcher write failed; retrying under /tmp fallback', {
227
+ primaryPath: launcher.guestPath,
228
+ code: primary.code,
229
+ fallbackPath: VM_AGENT_TMP_FALLBACK_PATH,
230
+ });
231
+ const fallback = await this.writeGuestFile(vm, { guestPath: VM_AGENT_TMP_FALLBACK_PATH, content: launcher.content, mode: VM_AGENT_LAUNCHER_MODE }, workdir);
232
+ if (fallback.code !== 0) {
233
+ throw new ByoContractError(`failed to stage the in-VM launcher: write to ${launcher.guestPath} exited ` +
234
+ `${primary.code} and the /tmp fallback (${VM_AGENT_TMP_FALLBACK_PATH}) exited ` +
235
+ `${fallback.code}. The BYO image must expose a writable rootfs overlay (Gondolin ` +
236
+ 'default `cow`) or a writable /tmp tmpfs.');
237
+ }
238
+ return VM_AGENT_TMP_FALLBACK_PATH;
239
+ }
240
+ /** Write one guest file via the base64-pipe exec; resolve its exit status. */
241
+ async writeGuestFile(vm, file, workdir) {
242
+ const exec = vm.exec({ command: writeFileCommand(file), workdir, timeoutMs: STAGE_TIMEOUT_MS });
243
+ exec.stdin.end();
244
+ return exec.exit;
245
+ }
246
+ /**
247
+ * Run the in-guest mise pre-install prep (issue 222) — create the rootfs install dir +
248
+ * the persistent cache subdirs and symlink mise's tool-download dir onto the cache (the
249
+ * pure `prepCommand` from core `runner/mise.ts`), BEFORE `mise install`, so a cold
250
+ * install's downloads persist across dispatches while the executable installs stay on
251
+ * the chmod-capable rootfs. Best-effort: a non-zero exit / timeout only costs a
252
+ * re-download next time (the install still succeeds on the rootfs), so it is LOGGED,
253
+ * never thrown. Always runs — mise provisioning is unconditional (issue 233).
254
+ */
255
+ async runMisePrepStep(vm, opts) {
256
+ const { code, stderr, timedOut } = await runBoundedExec(vm.exec({
257
+ command: opts.plan.mise.prepCommand,
258
+ workdir: opts.workdir,
259
+ env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
260
+ timeoutMs: STAGE_TIMEOUT_MS,
261
+ }), STAGE_TIMEOUT_MS);
262
+ if (timedOut || code !== 0) {
263
+ this.log.emit('warn', 'gondolin-dispatch: mise pre-install prep failed (continuing; downloads will not persist)', {
264
+ code,
265
+ timedOut,
266
+ stderr: stderr.trim().slice(0, 500),
267
+ });
268
+ }
269
+ }
270
+ /**
271
+ * Run the in-guest `mise install` step (issue 209) — provision node + the agent CLIs
272
+ * (the staged SYSTEM config at /etc/mise/config.toml) + any project toolchains (the
273
+ * workspace mise.toml) onto the ephemeral guest rootfs (issue 222; downloads cached on
274
+ * the bind mount), with cwd = workspace so the merged tool set is picked up. The install
275
+ * command + env are pure (core `runner/mise.ts`); a non-zero exit / timeout throws a
276
+ * typed ByoContractError carrying the operator-facing message + the guest's stderr tail,
277
+ * so a provisioning failure surfaces here rather than as a later opaque ENOENT (no node /
278
+ * no adapter shim) from the probe. Always runs — mise provisioning is unconditional
279
+ * (issue 233).
280
+ */
281
+ async runMiseInstallStep(vm, opts) {
282
+ const { code, stderr, timedOut } = await runMiseInstall(vm, {
283
+ workdir: opts.workdir,
284
+ command: opts.plan.mise.installCommand,
285
+ // The mise env (MISE_DATA_DIR + MISE_YES + npm_config_cache) rides this exec (not
286
+ // the boot env) so the install writes onto the rootfs, caches downloads on the bind
287
+ // mount, and answers mise's trust prompts.
288
+ env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
289
+ }, this.hasProjectMiseConfig, this.log, MISE_INSTALL_TIMEOUT_MS);
290
+ if (timedOut) {
291
+ throw new ByoContractError(this.miseInstallFailureMessage(null, `mise install timed out after ${MISE_INSTALL_TIMEOUT_MS} ms`));
292
+ }
293
+ if (code !== 0) {
294
+ throw new ByoContractError(this.miseInstallFailureMessage(code, stderr));
295
+ }
296
+ }
297
+ /**
298
+ * One bounded probe run under the launch PATH, AFTER staging and BEFORE launch:
299
+ * resolve the ABSOLUTE node + adapter paths from PATH (so the launch exec stays
300
+ * PATH-independent), assert Node≥21 / global WebSocket, and confirm the launcher
301
+ * materialized at `launcherGuestPath`. A non-zero exit (or unresolved paths) throws a
302
+ * typed ByoContractError with a precise, operator-facing message.
303
+ */
304
+ async probeGuest(vm, opts, launcherGuestPath) {
305
+ const adapterName = opts.adapterBin;
306
+ // The probe script (node-resolution decision + shell-injection-safe quoting) is
307
+ // an injected pure decider (core `runner/mise.ts:buildByoProbeScript`): it resolves
308
+ // the AGENT runtime node via `mise which node` run from `/` (system-scoped — a
309
+ // project mise.toml can't downgrade it). The exec carries the mise env (MISE_DATA_DIR)
310
+ // so the `mise which`/shim resolution sees the rootfs install dir the toolchain landed in.
311
+ const script = this.byoProbeScript(adapterName, launcherGuestPath);
312
+ const { code, stdout, stderr, timedOut } = await runBoundedExec(vm.exec({
313
+ command: ['/bin/sh', '-c', script],
314
+ workdir: opts.workdir,
315
+ env: { PATH: GUEST_AGENT_PATH, ...opts.plan.mise.env },
316
+ timeoutMs: PROBE_TIMEOUT_MS,
317
+ }), PROBE_TIMEOUT_MS);
318
+ if (timedOut) {
319
+ throw new ByoContractError(`BYO image probe timed out after ${PROBE_TIMEOUT_MS} ms before resolving node + ` +
320
+ `"${adapterName}" on PATH. Check that Node ≥ 21 and the adapter CLI are on PATH and ` +
321
+ 'that /bin/sh works in the guest.');
322
+ }
323
+ if (code !== 0) {
324
+ throw new ByoContractError(this.byoProbeFailureMessage(code, adapterName, stderr, GUEST_AGENT_PATH));
325
+ }
326
+ const [resolvedNode, resolvedAdapter] = stdout
327
+ .split('\n')
328
+ .map((s) => s.trim())
329
+ .filter((s) => s.length > 0);
330
+ if (!resolvedNode || !resolvedAdapter) {
331
+ throw new ByoContractError(`BYO image probe succeeded but did not resolve absolute node + adapter paths ` +
332
+ `(node="${resolvedNode ?? ''}", adapter="${resolvedAdapter ?? ''}"). The image must ` +
333
+ `expose "node" and "${adapterName}" on PATH.`);
334
+ }
335
+ return { nodeBin: resolvedNode, adapterBin: resolvedAdapter };
336
+ }
337
+ /**
338
+ * Launch the in-VM ACP agent. Stdin is end()ed immediately — ACP frames ride the /acp
339
+ * WebSocket, not the exec stdio; the exec channel is a process tether + diagnostic
340
+ * stderr pipe. Execs the ABSOLUTE node the probe resolved against the staged launcher
341
+ * path; SYMPHONY_ADAPTER_BIN in launchEnv is overridden with the probe's absolute
342
+ * adapter path so the adapter spawn is PATH-independent too.
343
+ */
344
+ launchAgent(vm, opts, probe, launcherGuestPath) {
345
+ const exec = vm.exec({
346
+ command: [probe.nodeBin, launcherGuestPath],
347
+ workdir: opts.workdir,
348
+ env: { ...opts.launchEnv, SYMPHONY_ADAPTER_BIN: probe.adapterBin },
349
+ timeoutMs: null,
350
+ });
351
+ exec.stdin.end();
352
+ exec.stderr.setEncoding('utf8');
353
+ exec.stderr.on('data', (chunk) => {
354
+ try {
355
+ opts.onStderr(chunk);
356
+ }
357
+ catch (err) {
358
+ this.log.emit('warn', 'gondolin-dispatch: stderr sink threw', { error: err.message });
359
+ }
360
+ });
361
+ // The exec is a fire-and-forget process tether: ACP drives the agent lifecycle over the
362
+ // /acp WebSocket and nothing awaits `exec.exit`. Observe it anyway so an in-VM agent that
363
+ // dies on its own (or the expected teardown kill, which the adapter resolves to a killed
364
+ // sentinel) is LOGGED rather than surfacing as an unhandled rejection that would crash the
365
+ // orchestrator. The adapter only re-rejects on genuine (non-kill) errors — log those.
366
+ void exec.exit.then(({ code, signal }) => this.log.emit('info', 'gondolin-dispatch: in-VM agent exec exited', { code, signal }), (err) => this.log.emit('warn', 'gondolin-dispatch: in-VM agent exec errored', { error: err.message }));
367
+ return exec;
368
+ }
369
+ /** Wrap the live VM + exec + registration into the idempotent teardown handle. */
370
+ buildHandle(vm, exec, registered) {
371
+ let torndown = false;
372
+ const log = this.log;
373
+ return {
374
+ vm,
375
+ exec,
376
+ teardown: async () => {
377
+ if (torndown)
378
+ return;
379
+ torndown = true;
380
+ await teardownDispatch(vm, exec, registered, log);
381
+ },
382
+ };
383
+ }
384
+ }
385
+ //# sourceMappingURL=gondolin-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gondolin-dispatch.js","sourceRoot":"","sources":["../../../../src/shell/adapter/gondolin-dispatch.ts"],"names":[],"mappings":"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"}