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,207 @@
1
+ // FCIS rewrite — pure VM-reaper KILL state machine (the per-session
2
+ // SIGTERM → grace → probe → SIGKILL escalation).
3
+ //
4
+ // Ported faithfully from the reference `VmResource.killSession`
5
+ // (REF: src/reconciler/vm.ts). The reference was a single async method that
6
+ // interleaved IO (`process.kill`, an inline `setTimeout` grace) with ledger
7
+ // bookkeeping. Under FCIS that method splits into two halves:
8
+ //
9
+ // • the SHELL drives the loop and performs the IO — it sends each host signal
10
+ // (a `process.kill`-backed `ProcessEffect`), sleeps the grace window (a
11
+ // `TimerEffect`), and probes liveness (signal-0). After each it hands the
12
+ // observed `KillStepResult` back here.
13
+ // • this CORE owns every DECISION as a pure fold: given the current `KillStep`
14
+ // (which signal/probe is in flight) and the `KillStepResult` the shell just
15
+ // observed, it returns the NEXT `KillStep` (wrapped as a `ReaperEffect` +,
16
+ // for `wait_grace`, the matching `TimerEffect`) PLUS the ledger transition
17
+ // to record. No IO, no clock, no `process`.
18
+ //
19
+ // The escalation, branch-for-branch with the reference:
20
+ //
21
+ // ① SIGTERM (start key, send SIGTERM).
22
+ // gone(ESRCH) → already dead → ledger done. (ref: ESRCH→done)
23
+ // no_perm(EPERM)→ can't signal → ledger error. (ref: throw→error)
24
+ // signalled → enter the grace window (wait_grace). (ref: await sleep)
25
+ // ② wait_grace (sleep killGraceMs), then probe.
26
+ // signalled → grace elapsed → probe liveness.
27
+ // ③ probe (signal 0 — liveness test).
28
+ // gone(ESRCH) → exited during grace → ledger done. (ref: !alive→done)
29
+ // no_perm(EPERM)→ alive but unreachable → ledger error. (ref: code!==ESRCH→error)
30
+ // alive(signal0 ok) → still running → escalate to SIGKILL.
31
+ // ④ SIGKILL.
32
+ // gone(ESRCH) → raced to exit → ledger done. (ref: ESRCH→done)
33
+ // signalled → killed → ledger done. (ref: success→done)
34
+ // no_perm(EPERM)→ unkillable → ledger error. (ref: throw→error)
35
+ //
36
+ // Pid safety (the keystone): the host signal is delivered by `process.kill`,
37
+ // which signals the whole PROCESS GROUP for `pid <= 0` and would target the
38
+ // orchestrator itself for `pid === selfPid`. `decideVm` already excludes those,
39
+ // but the reference re-guards once more before any signal leaves the shell
40
+ // ("belt-and-suspenders"). That guard is reproduced PURELY here in
41
+ // {@link beginKill}: an unsafe pid never yields a `signal` step — it yields an
42
+ // immediate terminal error decision, so the shell has no path to call
43
+ // `process.kill` on a bad pid.
44
+ //
45
+ // 100% SYNCHRONOUS. No async / await / Promise. No IO, no node: imports, no
46
+ // wall clock or randomness. Imports ONLY from src/types. (NodeNext ESM → .js
47
+ // extensions on relative imports.)
48
+ /**
49
+ * SIGTERM-to-SIGKILL grace period (ms). A session runner that ignores SIGTERM is
50
+ * SIGKILL'd after this delay. Mirrors the reference `DEFAULT_KILL_GRACE_MS`.
51
+ * Tests pass a small value so the grace path is observable in fast suites; the
52
+ * value is injected into {@link beginKill} (core never reads a config or a clock).
53
+ */
54
+ export const DEFAULT_KILL_GRACE_MS = 3_000;
55
+ /** The ledger key for one session's kill action — `kill_session:<pid>` (ref). */
56
+ export function killKey(pid) {
57
+ return `kill_session:${pid}`;
58
+ }
59
+ /** Wrap a `KillStep` as the `reaper` Effect the shell's interpreter drains. */
60
+ function reaperEffect(step) {
61
+ return { family: 'reaper', step };
62
+ }
63
+ /** The `timer.sleep` effect backing the grace window. */
64
+ function sleepEffect(ms) {
65
+ return { family: 'timer', kind: 'sleep', ms };
66
+ }
67
+ /** Whether a pid is safe to signal: a positive safe integer that isn't us. */
68
+ export function isSafeKillPid(pid, selfPid) {
69
+ // `process.kill(pid, sig)` signals the whole process group for `pid <= 0`
70
+ // and the orchestrator itself for `pid === selfPid` — both catastrophic.
71
+ return Number.isSafeInteger(pid) && pid > 0 && pid !== selfPid;
72
+ }
73
+ /**
74
+ * Begin the escalation for one `kill_session` action. Reproduces the reference
75
+ * belt-and-suspenders guard PURELY: an unsafe pid (self / `<= 0` / non-finite)
76
+ * never produces a `signal` step — it returns a terminal `done` state carrying
77
+ * an `error` ledger op, so the shell has no path to `process.kill` a bad pid.
78
+ *
79
+ * A safe pid yields the opening step: `start` the ledger row and emit the
80
+ * SIGTERM signal (the shell sends it, then folds the observed result via
81
+ * {@link foldKillStep}).
82
+ *
83
+ * @param graceMs Injected grace window (the shell read it from config). Carried
84
+ * into the eventual `wait_grace` step's sleep effect.
85
+ */
86
+ export function beginKill(action, selfPid) {
87
+ const key = killKey(action.pid);
88
+ if (!isSafeKillPid(action.pid, selfPid)) {
89
+ // Reference: `start(key)` then `error(key, msg)` — surfaced as a row so the
90
+ // dashboard shows the refusal — and NO signal is ever emitted.
91
+ return {
92
+ next: { kind: 'done', pid: action.pid },
93
+ effects: [],
94
+ ledger: { op: 'error', key, message: `refused to signal unsafe pid ${action.pid}` },
95
+ };
96
+ }
97
+ return {
98
+ next: { kind: 'signal', pid: action.pid, signal: 'SIGTERM' },
99
+ effects: [reaperEffect({ kind: 'signal', pid: action.pid, signal: 'SIGTERM' })],
100
+ ledger: { op: 'start', key },
101
+ };
102
+ }
103
+ /**
104
+ * The core fold: given the `step` whose effect was just executed and the
105
+ * `result` the shell observed, return the NEXT step + effects + ledger op.
106
+ *
107
+ * `graceMs` is the injected grace window (only consulted when transitioning into
108
+ * `wait_grace`). Every branch returns a fresh decision; nothing is mutated.
109
+ *
110
+ * Terminal states return `{ kind: 'done' }` with NO effects — the shell stops
111
+ * driving and applies the `ledger` op. Intermediate states return the next
112
+ * `reaper` step (and, for the grace window, the `timer.sleep`) and the loop
113
+ * continues.
114
+ */
115
+ export function foldKillStep(step, result, graceMs = DEFAULT_KILL_GRACE_MS) {
116
+ const pid = step.pid;
117
+ const key = killKey(pid);
118
+ const terminalDone = { kind: 'done', pid };
119
+ switch (step.kind) {
120
+ // ── ① SIGTERM / ④ SIGKILL share the same signal-result table. ──────────
121
+ case 'signal': {
122
+ switch (result.kind) {
123
+ case 'gone':
124
+ // ESRCH: already gone — treat as success (ref: ESRCH → done).
125
+ return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
126
+ case 'no_perm': {
127
+ // EPERM: can't deliver the signal — surface as an error and stop.
128
+ const phase = step.signal === 'SIGTERM' ? 'SIGTERM' : 'SIGKILL';
129
+ return {
130
+ next: terminalDone,
131
+ effects: [],
132
+ ledger: { op: 'error', key, message: `${phase} failed: EPERM` },
133
+ };
134
+ }
135
+ case 'signalled':
136
+ if (step.signal === 'SIGTERM') {
137
+ // Reference: `await sleep(graceMs)` then probe. Emit the grace
138
+ // window's sleep AND the next reaper step (wait_grace) so the shell
139
+ // sleeps before probing.
140
+ const next = { kind: 'wait_grace', pid, ms: graceMs };
141
+ return {
142
+ next,
143
+ effects: [sleepEffect(graceMs), reaperEffect(next)],
144
+ ledger: { op: 'none' },
145
+ };
146
+ }
147
+ // SIGKILL succeeded → terminal done (ref: success → done).
148
+ return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
149
+ case 'alive':
150
+ // A `signal`/`SIGKILL` reporting "still alive" is not a normal result
151
+ // path (the shell maps signal-send success to `signalled`); treat a
152
+ // surviving SIGKILL target as terminal success to avoid a kill loop,
153
+ // matching the reference (post-SIGKILL it always lands in done).
154
+ return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
155
+ }
156
+ // Exhaustive; unreachable.
157
+ return { next: terminalDone, effects: [], ledger: { op: 'none' } };
158
+ }
159
+ // ── ② grace window elapsed → probe liveness. ────────────────────────────
160
+ case 'wait_grace': {
161
+ // Reference: after the sleep, probe with signal 0. The sleep already ran
162
+ // (shell applied the timer.sleep); regardless of the observed result we
163
+ // advance to the probe step. No ledger change here.
164
+ const next = { kind: 'probe', pid };
165
+ return { next, effects: [reaperEffect(next)], ledger: { op: 'none' } };
166
+ }
167
+ // ── ③ probe (signal 0) → done / error / escalate to SIGKILL. ────────────
168
+ case 'probe': {
169
+ switch (result.kind) {
170
+ case 'gone':
171
+ // ESRCH from the probe: the process exited during the grace window
172
+ // (ref: `!alive` → done).
173
+ return { next: terminalDone, effects: [], ledger: { op: 'done', key } };
174
+ case 'no_perm':
175
+ // EPERM: alive but unreachable — surface as error (ref: code !== ESRCH
176
+ // → error, "assume alive but unkillable").
177
+ return {
178
+ next: terminalDone,
179
+ effects: [],
180
+ ledger: { op: 'error', key, message: 'alive-probe failed: EPERM' },
181
+ };
182
+ case 'alive':
183
+ case 'signalled': {
184
+ // Still alive after the grace → escalate to SIGKILL (ref: `alive` →
185
+ // SIGKILL). `signalled` from a signal-0 probe is treated the same as
186
+ // `alive` (the process accepted the no-op signal ⇒ it exists).
187
+ const next = { kind: 'signal', pid, signal: 'SIGKILL' };
188
+ return { next, effects: [reaperEffect(next)], ledger: { op: 'none' } };
189
+ }
190
+ }
191
+ // Exhaustive; unreachable.
192
+ return { next: terminalDone, effects: [], ledger: { op: 'none' } };
193
+ }
194
+ // ── terminal ─────────────────────────────────────────────────────────────
195
+ case 'done':
196
+ // No further work; a result observed against a terminal step is a no-op.
197
+ return { next: step, effects: [], ledger: { op: 'none' } };
198
+ }
199
+ }
200
+ /**
201
+ * Whether a `KillStep` is terminal (the shell stops driving the per-session
202
+ * escalation when it reaches this).
203
+ */
204
+ export function isKillTerminal(step) {
205
+ return step.kind === 'done';
206
+ }
207
+ //# sourceMappingURL=vm-reap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vm-reap.js","sourceRoot":"","sources":["../../../../src/core/reconcile/vm-reap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ // FCIS rewrite — pure workspace-janitor decision core.
2
+ //
3
+ // Functional-core port of the diff half of the original
4
+ // `src/reconciler/workspace.ts:WorkspaceResource.reconcile`. The original was an
5
+ // async class method that interleaved IO (tracker read, dir listing, base-ref
6
+ // lookup, per-dir git inspection, rm, create) with the diff logic and recorded
7
+ // every step into a `ResourceActionLedger`. In the FCIS layout ALL of that IO
8
+ // moves OUT into the shell:
9
+ //
10
+ // - The desired set (active non-terminal + in-flight identifiers with their
11
+ // current state) is SUPPLIED here as plain data (`WorkspaceObservedState.
12
+ // desired`). The shell does the (fail-closed) tracker read; if it throws,
13
+ // the shell never calls this decider — exactly matching the original's
14
+ // "bail and leave existing workspaces untouched" rule.
15
+ // - The dir listing, the source-repo base SHA, and the per-dir git inspection
16
+ // are SUPPLIED as plain data (`observed`, `baseRefSha`, `inspections`). When
17
+ // `baseRefSha` is null the shell couldn't resolve base → this decider skips
18
+ // drift detection entirely (orphan removal still fires), mirroring the
19
+ // original `if (baseRef === null) continue;`.
20
+ // - The merge-state guard the original applied INSIDE its create callback
21
+ // (`WorkspaceManager.ensureFor` skips eager recreation while the owning
22
+ // issue sits in the PR/merge state) is applied here as data: a desired
23
+ // entry whose `state === prMergeState` does NOT get a `create_workspace`.
24
+ //
25
+ // The decider RETURNS:
26
+ // - `actions`: `create_workspace` / `remove_workspace` `ReconcilerAction[]`
27
+ // the shell executes (each maps to a `workspace.ensure` / `workspace.remove`
28
+ // Effect). `remove` carries the sanitized dir name; `create` carries the raw
29
+ // operator-visible identifier (the shell's `ensure` re-sanitizes).
30
+ // - `marks`: non-destructive `mark_stale` / `mark_stuck` drift annotations the
31
+ // shell records into the ledger (the original never auto-removes for drift
32
+ // in v1 — it only annotates so the dashboard renders a badge).
33
+ // - `logs`: `LogEffect[]` so the shell can re-emit the same structured lines
34
+ // the original logged at each branch.
35
+ //
36
+ // Pure + synchronous: (data) -> data + Effect[]. Imports ONLY from src/types.
37
+ //
38
+ // HARD CONSTRAINTS (gate-enforced):
39
+ // - 100% SYNCHRONOUS. No async/await/Promise anywhere.
40
+ // - No IO, no node: imports, no process/fetch, no wall clock, no randomness.
41
+ // - Imports ONLY from src/types/**.
42
+ import { sanitizeWorkspaceKey } from '../workspace-key.js';
43
+ function log(level, message, fields) {
44
+ return fields === undefined
45
+ ? { family: 'log', kind: 'emit', level, message }
46
+ : { family: 'log', kind: 'emit', level, message, fields };
47
+ }
48
+ /**
49
+ * Pure janitor diff. Given the desired set (active + in-flight identifiers with
50
+ * state), the observed dirs on disk, the source repo's current base SHA, and the
51
+ * per-dir git inspections, return the create/remove actions, the drift marks,
52
+ * and the log effects.
53
+ *
54
+ * Branch parity with the original `WorkspaceResource.reconcile`:
55
+ * 1. Build `wanted`: sanitize in-flight ids first, then active ids (active
56
+ * wins on overlap so the tracker's authoritative state beats an in-flight
57
+ * target_state). Keyed by sanitized dir name → { identifier, state }.
58
+ * 2. For each observed dir: not in `wanted` ⇒ `remove_workspace` (stale_issue),
59
+ * UNLESS it carries a handoff-pending marker (`obs.handoffPending`) — a
60
+ * terminal issue whose push handoff failed, RETAINED so the only commit copy
61
+ * survives for recovery (234). Else mark present; if a base SHA is present,
62
+ * fold the inspection for drift (mark_stuck when there's agent work to lose,
63
+ * else mark_stale).
64
+ * 3. For each wanted id with no dir on disk ⇒ `create_workspace`, UNLESS the
65
+ * merge-state guard fires (its state === prMergeState).
66
+ */
67
+ export function decideWorkspace(obs) {
68
+ const actions = [];
69
+ const marks = [];
70
+ const logs = [];
71
+ let staleCount = 0;
72
+ let stuckCount = 0;
73
+ let createdCount = 0;
74
+ let lastError = null;
75
+ // Step 1 — build the desired map keyed by sanitized dir name. The original
76
+ // iterated in-flight first then active so active (the tracker's authoritative
77
+ // state) overwrites any overlapping in-flight entry. `obs.desired` here is the
78
+ // already-merged sequence the shell hands us in that same precedence order;
79
+ // we sanitize and last-write-wins to reproduce the overlap rule even if a
80
+ // caller supplies raw (in-flight, active) pairs in order.
81
+ const wanted = new Map();
82
+ for (const entry of obs.desired) {
83
+ wanted.set(sanitizeWorkspaceKey(entry.identifier), {
84
+ identifier: entry.identifier,
85
+ state: entry.state,
86
+ });
87
+ }
88
+ // Step 2 — reap orphans + annotate drift on the dirs that survive.
89
+ const present = new Set();
90
+ for (const { name } of obs.observed) {
91
+ if (!wanted.has(name)) {
92
+ // A terminal issue whose phase-8 handoff push FAILED left a marker: the only
93
+ // copy of its completed commit lives in this dir, so RETAIN it (skip the reap)
94
+ // until it's pushed/recovered — reaping it would be unrecoverable loss (234).
95
+ if (obs.handoffPending.has(name)) {
96
+ logs.push(log('warn', 'workspace reconcile: retained (handoff pending)', { identifier: name, reason: 'handoff_pending' }));
97
+ continue;
98
+ }
99
+ actions.push({ kind: 'remove_workspace', identifier: name });
100
+ logs.push(log('info', 'workspace reconcile: removed', { identifier: name, reason: 'stale_issue' }));
101
+ continue;
102
+ }
103
+ present.add(name);
104
+ // In the desired set. Drift detection needs a base SHA to compare against;
105
+ // null means the shell couldn't resolve base this pass — skip (workspace ok).
106
+ if (obs.baseRefSha === null)
107
+ continue;
108
+ const inspection = obs.inspections[name];
109
+ // No inspection supplied (shell skipped or the inspect call failed) — treat
110
+ // as ok, matching the original's `catch { continue; }` around inspect.
111
+ if (inspection === undefined)
112
+ continue;
113
+ if (inspection.head === null)
114
+ continue;
115
+ // Workspace has no local copy of the base branch — operator likely deleted
116
+ // it. Skip drift detection rather than guess.
117
+ if (inspection.workspaceBaseSha === null)
118
+ continue;
119
+ // Drift = workspace's frozen base SHA disagrees with source's current base
120
+ // SHA. Any disagreement counts (fast-forward, divergence, rewind all surface
121
+ // as "the operator's base moved out from under us").
122
+ if (inspection.workspaceBaseSha === obs.baseRefSha)
123
+ continue;
124
+ // Drift detected. v1 never auto-removes for drift; annotate and move on.
125
+ if (inspection.hasUncommitted || inspection.commitsAheadOfBase > 0) {
126
+ stuckCount += 1;
127
+ const reason = inspection.hasUncommitted
128
+ ? 'uncommitted changes present'
129
+ : `${inspection.commitsAheadOfBase} commit(s) ahead of base`;
130
+ lastError = `workspace ${name} stuck: base advanced and ${reason}`;
131
+ marks.push({ status: 'stuck', identifier: name, reason });
132
+ logs.push(log('warn', 'workspace reconcile: stuck (drift, agent work present)', { identifier: name, reason }));
133
+ continue;
134
+ }
135
+ staleCount += 1;
136
+ const staleReason = 'base advanced past workspace HEAD; re-clone is opt-in';
137
+ lastError = `workspace ${name} stale: ${staleReason}`;
138
+ marks.push({ status: 'stale', identifier: name, reason: staleReason });
139
+ logs.push(log('info', 'workspace reconcile: stale (drift, no agent work to lose)', { identifier: name, reason: staleReason }));
140
+ }
141
+ // Step 3 — create any desired identifier with no dir on disk, modulo the
142
+ // merge-state guard. The original deferred to `WorkspaceManager.ensureFor`,
143
+ // which is idempotent; the guard (skip while the owning issue sits in the
144
+ // PR/merge state) was applied inside that create callback. Here it's data:
145
+ // `state === prMergeState` ⇒ no create_workspace.
146
+ for (const [key, { identifier, state }] of wanted) {
147
+ if (present.has(key))
148
+ continue;
149
+ if (obs.prMergeState !== null && state === obs.prMergeState) {
150
+ logs.push(log('debug', 'workspace reconcile: create skipped (merge-state guard)', {
151
+ identifier,
152
+ state,
153
+ }));
154
+ continue;
155
+ }
156
+ actions.push({ kind: 'create_workspace', identifier });
157
+ createdCount += 1;
158
+ logs.push(log('info', 'workspace reconcile: created', { identifier, state }));
159
+ }
160
+ return { actions, marks, logs, staleCount, stuckCount, createdCount, lastError };
161
+ }
162
+ //# sourceMappingURL=workspace-decide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-decide.js","sourceRoot":"","sources":["../../../../src/core/reconcile/workspace-decide.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,231 @@
1
+ // FCIS rewrite — pure per-issue run-summary reducer.
2
+ //
3
+ // Functional core: the single export here is a pure, SYNCHRONOUS (data) -> data
4
+ // reduction. No IO, no async/Promise, no clock, no randomness, no node: imports.
5
+ // Imports ONLY from src/types. Ports src/runlog.ts:summarizeRunLog and its
6
+ // private helpers (buildAttemptSpans / collectTransitions / buildStatePath /
7
+ // perStateStats / collectRejections / collectTimeouts / terminalOf / prFrom /
8
+ // wallClockTotal) verbatim in behavior.
9
+ //
10
+ // WHAT MOVED to the shell vs the original:
11
+ // - The original `summarizeRunLog` defaulted `generatedAt` to
12
+ // `new Date().toISOString()`. A pure core cannot read the wall clock, so
13
+ // `generatedAt` is now a REQUIRED parameter. The composition root reads it
14
+ // from the injected Clock port (clock.iso()) and passes it in. Everything
15
+ // else (timestamp PARSING via the deterministic Date.parse on caller-
16
+ // supplied ISO strings) stays pure — it derives data from inputs only.
17
+ // - The RunLog class lifecycle (open/record/captureLifecycle/writeSummary/
18
+ // close, the JSONL stream, the *.summary.json fs write) is NOT here; that is
19
+ // RunLog Effect execution in the shell. This module is only the reducer the
20
+ // write_summary effect consumes.
21
+ //
22
+ // NOTE on Date.parse: parsing a caller-provided ISO-8601 string is deterministic
23
+ // and does not read the ambient clock, so it is permitted in core. We never call
24
+ // Date.now() / new Date() with no argument.
25
+ import { RUN_SUMMARY_SCHEMA_VERSION } from '../../types/runlog.js';
26
+ const NOTE_CAP = 4000;
27
+ const TIMEOUT_RE = /timeout|timed out|stall|prompt_timeout|did not connect|bridge/i;
28
+ const PR_URL_RE = /(https?:\/\/[^\s)]+\/pull\/(\d+))/;
29
+ function fieldsOf(e) {
30
+ return e.fields && typeof e.fields === 'object' ? e.fields : {};
31
+ }
32
+ function asStr(v) {
33
+ return typeof v === 'string' ? v : null;
34
+ }
35
+ function asNum(v) {
36
+ return typeof v === 'number' && Number.isFinite(v) ? v : null;
37
+ }
38
+ function isBudgetExhausted(reason) {
39
+ return reason !== null && /max_turns/i.test(reason);
40
+ }
41
+ function spanDurationMs(s) {
42
+ if (!s.ended_at)
43
+ return 0;
44
+ const a = Date.parse(s.started_at);
45
+ const b = Date.parse(s.ended_at);
46
+ return Number.isFinite(a) && Number.isFinite(b) && b >= a ? b - a : 0;
47
+ }
48
+ /** Pair `attempt_started`/`attempt_ended` events in order into per-attempt spans. */
49
+ function buildAttemptSpans(entries) {
50
+ const spans = [];
51
+ for (const e of entries) {
52
+ if (e.channel !== 'system')
53
+ continue;
54
+ const f = fieldsOf(e);
55
+ if (e.event === 'attempt_started') {
56
+ spans.push({
57
+ attempt: asNum(f.attempt) ?? spans.length,
58
+ state: asStr(f.issue_state) ?? 'unknown',
59
+ max_turns: asNum(f.max_turns),
60
+ turns_used: 0,
61
+ reason: null,
62
+ started_at: e.ts,
63
+ ended_at: null,
64
+ });
65
+ }
66
+ else if (e.event === 'attempt_ended') {
67
+ const open = spans[spans.length - 1];
68
+ if (open && open.ended_at === null) {
69
+ open.turns_used = asNum(f.turns_completed) ?? 0;
70
+ open.reason = asStr(f.reason);
71
+ open.ended_at = e.ts;
72
+ }
73
+ }
74
+ }
75
+ return spans;
76
+ }
77
+ function collectTransitions(entries) {
78
+ const out = [];
79
+ for (const e of entries) {
80
+ if (e.channel !== 'system' || e.event !== 'transition')
81
+ continue;
82
+ const f = fieldsOf(e);
83
+ out.push({
84
+ from_state: asStr(f.from_state) ?? 'unknown',
85
+ to_state: asStr(f.to_state) ?? 'unknown',
86
+ notes: asStr(f.notes) ?? '',
87
+ actor: asStr(f.actor),
88
+ terminal: f.terminal === true,
89
+ rerouted: f.rerouted === true,
90
+ });
91
+ }
92
+ return out;
93
+ }
94
+ function collapseConsecutive(seq) {
95
+ const out = [];
96
+ for (const s of seq) {
97
+ if (out[out.length - 1] !== s)
98
+ out.push(s);
99
+ }
100
+ return out;
101
+ }
102
+ /** State path backbone is the per-attempt states (every dispatch logs one); the terminal state is appended. */
103
+ function buildStatePath(spans, transitions, terminalState) {
104
+ let path = collapseConsecutive(spans.map((s) => s.state));
105
+ if (path.length === 0 && transitions.length > 0) {
106
+ path = collapseConsecutive([transitions[0].from_state, ...transitions.map((t) => t.to_state)]);
107
+ }
108
+ if (terminalState && path[path.length - 1] !== terminalState)
109
+ path.push(terminalState);
110
+ return path;
111
+ }
112
+ function perStateStats(spans) {
113
+ const order = [];
114
+ const byState = new Map();
115
+ for (const s of spans) {
116
+ let stat = byState.get(s.state);
117
+ if (!stat) {
118
+ stat = {
119
+ state: s.state,
120
+ attempts: 0,
121
+ turns_used: 0,
122
+ max_turns: null,
123
+ budget_exhausted: false,
124
+ wall_clock_ms: 0,
125
+ };
126
+ byState.set(s.state, stat);
127
+ order.push(s.state);
128
+ }
129
+ stat.attempts += 1;
130
+ stat.turns_used += s.turns_used;
131
+ if (s.max_turns !== null)
132
+ stat.max_turns = s.max_turns;
133
+ if (isBudgetExhausted(s.reason))
134
+ stat.budget_exhausted = true;
135
+ stat.wall_clock_ms += spanDurationMs(s);
136
+ }
137
+ return order.map((st) => byState.get(st));
138
+ }
139
+ function capNotes(notes) {
140
+ return notes.length > NOTE_CAP ? notes.slice(0, NOTE_CAP) + '…[truncated]' : notes;
141
+ }
142
+ /**
143
+ * A review rejection is a non-reroute transition back to the INITIAL implementing
144
+ * state (where the issue started). In the shipped Todo→Review→Done flow that is
145
+ * exactly a Review→Todo kick-back; the definition stays workflow-agnostic.
146
+ */
147
+ function collectRejections(transitions, initialState) {
148
+ if (initialState === null)
149
+ return [];
150
+ const out = [];
151
+ for (const t of transitions) {
152
+ if (t.rerouted)
153
+ continue;
154
+ if (t.to_state === initialState && t.from_state !== t.to_state) {
155
+ out.push({ from_state: t.from_state, to_state: t.to_state, actor: t.actor, notes: capNotes(t.notes) });
156
+ }
157
+ }
158
+ return out;
159
+ }
160
+ function collectTimeouts(spans) {
161
+ const out = [];
162
+ for (const s of spans) {
163
+ if (s.reason !== null && TIMEOUT_RE.test(s.reason)) {
164
+ out.push({ attempt: s.attempt, state: s.state, reason: s.reason });
165
+ }
166
+ }
167
+ return out;
168
+ }
169
+ function terminalOf(transitions) {
170
+ let terminal = null;
171
+ for (const t of transitions) {
172
+ if (t.terminal)
173
+ terminal = t;
174
+ }
175
+ if (!terminal)
176
+ return { state: null, outcome: 'incomplete' };
177
+ return { state: terminal.to_state, outcome: /cancel/i.test(terminal.to_state) ? 'cancelled' : 'completed' };
178
+ }
179
+ function prFrom(actionsStdout) {
180
+ const m = PR_URL_RE.exec(actionsStdout);
181
+ if (!m)
182
+ return { number: null, url: null };
183
+ return { url: m[1], number: Number.parseInt(m[2], 10) };
184
+ }
185
+ function wallClockTotal(entries) {
186
+ if (entries.length === 0)
187
+ return null;
188
+ const a = Date.parse(entries[0].ts);
189
+ const b = Date.parse(entries[entries.length - 1].ts);
190
+ return Number.isFinite(a) && Number.isFinite(b) && b >= a ? b - a : null;
191
+ }
192
+ /**
193
+ * Reduce a per-issue lifecycle event list into a {@link RunSummary}. Pure and
194
+ * deterministic. Tolerant of partial streams — every field degrades to a
195
+ * sensible empty/null value.
196
+ */
197
+ export function summarizeRunLog(input) {
198
+ const spans = buildAttemptSpans(input.entries);
199
+ const transitions = collectTransitions(input.entries);
200
+ const term = terminalOf(transitions);
201
+ const statePath = buildStatePath(spans, transitions, term.state);
202
+ const initialState = statePath[0] ?? spans[0]?.state ?? null;
203
+ const rejections = collectRejections(transitions, initialState);
204
+ const perState = perStateStats(spans);
205
+ const pr = prFrom(input.actionsStdout);
206
+ const conflictRoutes = transitions
207
+ .filter((t) => t.rerouted)
208
+ .map((t) => ({ from_state: t.from_state, to_state: t.to_state }));
209
+ return {
210
+ schema_version: RUN_SUMMARY_SCHEMA_VERSION,
211
+ issue_id: input.issueId,
212
+ issue_identifier: input.issueIdentifier,
213
+ state_path: statePath,
214
+ attempts: spans.length,
215
+ per_state: perState,
216
+ review_rejections: rejections.length,
217
+ rejection_notes: rejections,
218
+ turn_budget_exhausted: perState.some((s) => s.budget_exhausted),
219
+ timeouts: collectTimeouts(spans),
220
+ conflict_routes: conflictRoutes,
221
+ terminal_state: term.state,
222
+ terminal_outcome: term.outcome,
223
+ pr_number: pr.number,
224
+ pr_url: pr.url,
225
+ first_event_at: input.entries[0]?.ts ?? null,
226
+ last_event_at: input.entries[input.entries.length - 1]?.ts ?? null,
227
+ wall_clock_ms_total: wallClockTotal(input.entries),
228
+ generated_at: input.generatedAt,
229
+ };
230
+ }
231
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../../src/core/runlog/summary.ts"],"names":[],"mappings":"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"}