@sema-agent/server 1.323.0 → 2.0.1

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 (565) hide show
  1. package/dist/approval-hmac.d.ts +40 -0
  2. package/dist/approval-hmac.js +67 -0
  3. package/dist/approval.d.ts +31 -0
  4. package/dist/approval.js +72 -4
  5. package/dist/audit.d.ts +26 -0
  6. package/dist/audit.js +40 -1
  7. package/dist/auth-bridge.d.ts +10 -0
  8. package/dist/auth-bridge.js +47 -4
  9. package/dist/auth-keys.d.ts +19 -0
  10. package/dist/auth-keys.js +13 -0
  11. package/dist/bake-runner/main.d.ts +5 -0
  12. package/dist/bake-runner/main.js +43 -4
  13. package/dist/bake-runner/protocol.d.ts +57 -0
  14. package/dist/bake-runner/protocol.js +58 -3
  15. package/dist/bake-runner/runner.d.ts +54 -0
  16. package/dist/bake-runner/runner.js +87 -5
  17. package/dist/bench/l8/artifact.d.ts +63 -0
  18. package/dist/bench/l8/artifact.js +61 -2
  19. package/dist/bench/l8/escape.d.ts +36 -0
  20. package/dist/bench/l8/escape.js +25 -0
  21. package/dist/bench/l8/index.d.ts +14 -0
  22. package/dist/bench/l8/index.js +14 -0
  23. package/dist/bench/l8/probes.d.ts +74 -0
  24. package/dist/bench/l8/probes.js +60 -0
  25. package/dist/bench/l8/run-probes.d.ts +43 -0
  26. package/dist/bench/l8/run-probes.js +45 -2
  27. package/dist/bench/s1/arms.d.ts +126 -0
  28. package/dist/bench/s1/arms.js +188 -13
  29. package/dist/bench/s1/live-deps.d.ts +66 -0
  30. package/dist/bench/s1/live-deps.js +249 -11
  31. package/dist/bench/s1/oracle.d.ts +49 -0
  32. package/dist/bench/s1/oracle.js +36 -1
  33. package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
  34. package/dist/bench/s1/repair-oracle-adapter.js +30 -0
  35. package/dist/bench/s1/reviewer.d.ts +38 -0
  36. package/dist/bench/s1/reviewer.js +34 -0
  37. package/dist/bench/s1/row.d.ts +77 -0
  38. package/dist/bench/s1/row.js +62 -0
  39. package/dist/bench/s1/run-firm.d.ts +47 -0
  40. package/dist/bench/s1/run-firm.js +70 -4
  41. package/dist/bench/s1/runner-ctx.d.ts +71 -0
  42. package/dist/bench/s1/runner-ctx.js +36 -0
  43. package/dist/bench/s1/tasks.d.ts +108 -0
  44. package/dist/bench/s1/tasks.js +115 -0
  45. package/dist/boot/budget-tracing.d.ts +48 -0
  46. package/dist/boot/budget-tracing.js +86 -0
  47. package/dist/boot/config-center.d.ts +62 -0
  48. package/dist/boot/config-center.js +995 -0
  49. package/dist/boot/coordinators.d.ts +33 -0
  50. package/dist/boot/coordinators.js +97 -0
  51. package/dist/boot/execution-env.d.ts +26 -0
  52. package/dist/boot/execution-env.js +370 -0
  53. package/dist/boot/leader.d.ts +27 -0
  54. package/dist/boot/leader.js +81 -0
  55. package/dist/boot/reapers.d.ts +53 -0
  56. package/dist/boot/reapers.js +252 -0
  57. package/dist/boot/resolve-spec.d.ts +70 -0
  58. package/dist/boot/resolve-spec.js +1072 -0
  59. package/dist/boot/runner-deps.d.ts +101 -0
  60. package/dist/boot/runner-deps.js +343 -0
  61. package/dist/boot/runtime-caps.d.ts +21 -0
  62. package/dist/boot/runtime-caps.js +62 -0
  63. package/dist/boot/session-faces.d.ts +57 -0
  64. package/dist/boot/session-faces.js +157 -0
  65. package/dist/boot/shutdown.d.ts +50 -0
  66. package/dist/boot/shutdown.js +129 -0
  67. package/dist/boot/stores.d.ts +32 -0
  68. package/dist/boot/stores.js +361 -0
  69. package/dist/boot/workflow-orchestration.d.ts +46 -0
  70. package/dist/boot/workflow-orchestration.js +150 -0
  71. package/dist/boot-reclaim.d.ts +19 -0
  72. package/dist/boot-reclaim.js +20 -0
  73. package/dist/brain.d.ts +25 -0
  74. package/dist/brain.js +61 -1
  75. package/dist/budget.d.ts +66 -0
  76. package/dist/budget.js +128 -4
  77. package/dist/capabilities/builtin-tools.d.ts +3 -0
  78. package/dist/capabilities/builtin-tools.js +3 -0
  79. package/dist/capabilities/center-plugins.d.ts +17 -1
  80. package/dist/capabilities/center-plugins.js +45 -4
  81. package/dist/capabilities/center-prompts.d.ts +46 -0
  82. package/dist/capabilities/center-prompts.js +57 -3
  83. package/dist/capabilities/code-review-council.d.ts +28 -0
  84. package/dist/capabilities/code-review-council.js +40 -7
  85. package/dist/capabilities/collab-wire.d.ts +2 -0
  86. package/dist/capabilities/collab-workflows.d.ts +7 -0
  87. package/dist/capabilities/collab-workflows.js +44 -1
  88. package/dist/capabilities/oa-tools.d.ts +6 -0
  89. package/dist/capabilities/oa-tools.js +10 -0
  90. package/dist/capabilities/prompt.d.ts +14 -0
  91. package/dist/capabilities/prompt.js +14 -0
  92. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  93. package/dist/capabilities/prompts/code-review.js +14 -0
  94. package/dist/capabilities/prompts/identity.d.ts +6 -0
  95. package/dist/capabilities/prompts/identity.js +6 -0
  96. package/dist/capabilities/prompts/team.d.ts +4 -0
  97. package/dist/capabilities/prompts/team.js +4 -0
  98. package/dist/capabilities/repo-tools.d.ts +11 -0
  99. package/dist/capabilities/repo-tools.js +8 -0
  100. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  101. package/dist/capabilities/sandbox-file-send.js +91 -3
  102. package/dist/capabilities/scenarios.d.ts +130 -0
  103. package/dist/capabilities/scenarios.js +180 -7
  104. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  105. package/dist/capabilities/select-environment-tool.js +30 -0
  106. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  107. package/dist/capabilities/send-user-file-tool.js +65 -1
  108. package/dist/capabilities/skills.d.ts +29 -0
  109. package/dist/capabilities/skills.js +13 -2
  110. package/dist/capabilities/team.d.ts +22 -0
  111. package/dist/capabilities/team.js +22 -2
  112. package/dist/capabilities/tool-defer.d.ts +26 -0
  113. package/dist/capabilities/tool-defer.js +3 -0
  114. package/dist/config-center/apply-effective.d.ts +65 -0
  115. package/dist/config-center/apply-effective.js +204 -12
  116. package/dist/config-center/http-client.d.ts +34 -0
  117. package/dist/config-center/http-client.js +68 -0
  118. package/dist/config-center/restart-signal.d.ts +22 -0
  119. package/dist/config-center/restart-signal.js +39 -0
  120. package/dist/config-center/skills-mcp.d.ts +20 -1
  121. package/dist/config-center/skills-mcp.js +42 -7
  122. package/dist/config-center/types.d.ts +92 -1
  123. package/dist/config-lkg.d.ts +12 -0
  124. package/dist/config-lkg.js +41 -0
  125. package/dist/config-provider.d.ts +78 -0
  126. package/dist/config-provider.js +165 -2
  127. package/dist/config-types.d.ts +585 -1
  128. package/dist/config.d.ts +78 -2
  129. package/dist/config.js +874 -301
  130. package/dist/degenerate-instrument.d.ts +38 -0
  131. package/dist/degenerate-instrument.js +55 -3
  132. package/dist/elicitation.d.ts +39 -0
  133. package/dist/elicitation.js +87 -3
  134. package/dist/env-facts.d.ts +61 -0
  135. package/dist/env-facts.js +73 -7
  136. package/dist/fleet/fleet-bus.d.ts +185 -0
  137. package/dist/fleet/fleet-bus.js +333 -27
  138. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  139. package/dist/fleet/subagent-tail-bus.js +33 -2
  140. package/dist/fleet-client.d.ts +38 -0
  141. package/dist/fleet-client.js +44 -9
  142. package/dist/fleet-lease.d.ts +46 -0
  143. package/dist/fleet-lease.js +73 -5
  144. package/dist/hooks/branch-transcript.d.ts +8 -0
  145. package/dist/hooks/branch-transcript.js +33 -0
  146. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  147. package/dist/hooks/cc-stop-prompt.js +43 -1
  148. package/dist/hooks/hook-llm.d.ts +15 -0
  149. package/dist/hooks/hook-llm.js +47 -0
  150. package/dist/hooks/hook-runner.d.ts +89 -0
  151. package/dist/hooks/hook-runner.js +327 -18
  152. package/dist/http/idempotency.d.ts +31 -0
  153. package/dist/http/idempotency.js +34 -0
  154. package/dist/http/principal-gate.d.ts +17 -0
  155. package/dist/http/principal-gate.js +35 -3
  156. package/dist/http/route-ctx.d.ts +36 -0
  157. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  158. package/dist/http/routes/approvals-assistant.js +253 -23
  159. package/dist/http/routes/attachments.js +22 -4
  160. package/dist/http/routes/capabilities.d.ts +7 -0
  161. package/dist/http/routes/capabilities.js +202 -1
  162. package/dist/http/routes/fleet.d.ts +6 -0
  163. package/dist/http/routes/fleet.js +94 -5
  164. package/dist/http/routes/images.d.ts +17 -0
  165. package/dist/http/routes/images.js +222 -14
  166. package/dist/http/routes/leader.d.ts +7 -0
  167. package/dist/http/routes/leader.js +10 -0
  168. package/dist/http/routes/memory-policy.d.ts +6 -0
  169. package/dist/http/routes/memory-policy.js +38 -6
  170. package/dist/http/routes/notify-wake.d.ts +10 -0
  171. package/dist/http/routes/notify-wake.js +19 -3
  172. package/dist/http/routes/observability.d.ts +6 -0
  173. package/dist/http/routes/observability.js +19 -2
  174. package/dist/http/routes/runs.d.ts +15 -0
  175. package/dist/http/routes/runs.js +464 -41
  176. package/dist/http/routes/session-sync.d.ts +15 -0
  177. package/dist/http/routes/session-sync.js +229 -19
  178. package/dist/http/routes/sessions-list.d.ts +6 -0
  179. package/dist/http/routes/sessions-list.js +35 -4
  180. package/dist/http/routes/sessions.d.ts +14 -0
  181. package/dist/http/routes/sessions.js +176 -31
  182. package/dist/http/routes/side-query.d.ts +8 -0
  183. package/dist/http/routes/side-query.js +26 -1
  184. package/dist/http/routes/tasks.d.ts +18 -0
  185. package/dist/http/routes/tasks.js +501 -38
  186. package/dist/http/routes/trace-usage.d.ts +10 -0
  187. package/dist/http/routes/trace-usage.js +66 -14
  188. package/dist/http/routes/workflows.d.ts +12 -0
  189. package/dist/http/routes/workflows.js +180 -19
  190. package/dist/http/run-meta.d.ts +11 -0
  191. package/dist/http/run-meta.js +6 -0
  192. package/dist/http/send.d.ts +19 -0
  193. package/dist/http/send.js +11 -0
  194. package/dist/http/server.d.ts +255 -0
  195. package/dist/http/server.js +921 -75
  196. package/dist/http/sse-log.d.ts +15 -0
  197. package/dist/http/sse-log.js +16 -0
  198. package/dist/http/tar.d.ts +9 -0
  199. package/dist/http/tar.js +21 -5
  200. package/dist/http/wire-gate.d.ts +9 -0
  201. package/dist/http/wire-gate.js +9 -0
  202. package/dist/http/wire-types.d.ts +187 -0
  203. package/dist/http/workspace-content.d.ts +8 -0
  204. package/dist/http/workspace-content.js +10 -0
  205. package/dist/images/bake-validate.d.ts +63 -0
  206. package/dist/images/bake-validate.js +71 -1
  207. package/dist/images/manifest.d.ts +19 -0
  208. package/dist/images/manifest.js +6 -1
  209. package/dist/index.d.ts +1 -5
  210. package/dist/index.js +10 -5
  211. package/dist/key-resolver.d.ts +23 -0
  212. package/dist/key-resolver.js +27 -2
  213. package/dist/leader/diffout.d.ts +23 -0
  214. package/dist/leader/diffout.js +8 -1
  215. package/dist/leader/diffup.d.ts +32 -0
  216. package/dist/leader/diffup.js +43 -0
  217. package/dist/leader/endpoint.d.ts +20 -0
  218. package/dist/leader/endpoint.js +25 -2
  219. package/dist/leader/fanout.d.ts +60 -0
  220. package/dist/leader/fanout.js +29 -3
  221. package/dist/leader/grader-env-factory.d.ts +74 -0
  222. package/dist/leader/grader-env-factory.js +62 -3
  223. package/dist/leader/leader.d.ts +97 -0
  224. package/dist/leader/leader.js +151 -4
  225. package/dist/leader/merge.d.ts +94 -0
  226. package/dist/leader/merge.js +112 -9
  227. package/dist/leader/planner.d.ts +52 -0
  228. package/dist/leader/planner.js +47 -3
  229. package/dist/leader/repair-oracle.d.ts +61 -0
  230. package/dist/leader/repair-oracle.js +59 -1
  231. package/dist/leader/repair-wire.d.ts +78 -0
  232. package/dist/leader/repair-wire.js +79 -2
  233. package/dist/leader/wire.d.ts +79 -0
  234. package/dist/leader/wire.js +255 -8
  235. package/dist/lsp/e2b-bridge.d.ts +16 -0
  236. package/dist/lsp/e2b-bridge.js +32 -4
  237. package/dist/lsp/e2b-manager.d.ts +10 -0
  238. package/dist/lsp/e2b-manager.js +18 -2
  239. package/dist/lsp/lsp-frames.d.ts +12 -0
  240. package/dist/lsp/lsp-frames.js +12 -0
  241. package/dist/lsp/manager.d.ts +12 -0
  242. package/dist/lsp/manager.js +35 -2
  243. package/dist/lsp/types.d.ts +10 -0
  244. package/dist/lsp/ws-transport.d.ts +12 -0
  245. package/dist/lsp/ws-transport.js +53 -5
  246. package/dist/lsp-evict.d.ts +14 -0
  247. package/dist/lsp-evict.js +15 -1
  248. package/dist/main.js +530 -2129
  249. package/dist/memory-export.d.ts +1 -0
  250. package/dist/memory-export.js +4 -0
  251. package/dist/memory-scope.d.ts +49 -0
  252. package/dist/memory-scope.js +87 -4
  253. package/dist/memory-sync-client.d.ts +24 -0
  254. package/dist/memory-sync-client.js +41 -2
  255. package/dist/memory-sync.d.ts +23 -0
  256. package/dist/memory-sync.js +70 -1
  257. package/dist/model-select.d.ts +39 -0
  258. package/dist/model-select.js +42 -1
  259. package/dist/observability/cost-quota.d.ts +20 -0
  260. package/dist/observability/cost-quota.js +4 -0
  261. package/dist/observability/cost-taxonomy.d.ts +45 -0
  262. package/dist/observability/cost-taxonomy.js +34 -0
  263. package/dist/observability/logger.d.ts +1 -0
  264. package/dist/observability/logger.js +6 -0
  265. package/dist/observability/metrics.d.ts +13 -0
  266. package/dist/observability/metrics.js +63 -0
  267. package/dist/observability/otel-exporter.d.ts +9 -0
  268. package/dist/observability/otel-exporter.js +11 -3
  269. package/dist/observability/principal-context.d.ts +9 -0
  270. package/dist/observability/principal-context.js +9 -0
  271. package/dist/observability/prompt-manifest.d.ts +37 -0
  272. package/dist/observability/prompt-manifest.js +35 -1
  273. package/dist/observability/rate-limit.d.ts +10 -0
  274. package/dist/observability/rate-limit.js +1 -0
  275. package/dist/observability/tool-trace.d.ts +24 -0
  276. package/dist/observability/tool-trace.js +41 -1
  277. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  278. package/dist/orchestration/hardened-vm-runner.js +119 -4
  279. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  280. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  281. package/dist/orchestration/hardened-vm-worker.js +27 -0
  282. package/dist/orchestration/subagent-steer.d.ts +44 -0
  283. package/dist/orchestration/subagent-steer.js +45 -1
  284. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  285. package/dist/orchestration/workflow-agent-steer.js +80 -1
  286. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  287. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  288. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  289. package/dist/orchestration/workflow-notify-journal.js +187 -13
  290. package/dist/parked-decide.d.ts +61 -0
  291. package/dist/parked-decide.js +58 -1
  292. package/dist/per-task-image.d.ts +54 -0
  293. package/dist/per-task-image.js +41 -0
  294. package/dist/plan-cache-probe.d.ts +35 -0
  295. package/dist/plan-cache-probe.js +18 -3
  296. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  297. package/dist/plugins/approval-exemption-store.js +28 -2
  298. package/dist/plugins/approval-store-sql.d.ts +64 -0
  299. package/dist/plugins/approval-store-sql.js +32 -0
  300. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  301. package/dist/plugins/background-agent-store-sql.js +91 -4
  302. package/dist/plugins/background-shell-support.d.ts +98 -0
  303. package/dist/plugins/background-shell-support.js +117 -13
  304. package/dist/plugins/blob-backend.d.ts +104 -0
  305. package/dist/plugins/blob-backend.js +163 -6
  306. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  307. package/dist/plugins/breaker-state-sql.js +46 -8
  308. package/dist/plugins/caching-session-store.d.ts +42 -0
  309. package/dist/plugins/caching-session-store.js +63 -3
  310. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  311. package/dist/plugins/checkpoint-store-sql.js +239 -11
  312. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  313. package/dist/plugins/file-outcome-sink.js +9 -0
  314. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  315. package/dist/plugins/file-resume-anchor-store.js +43 -4
  316. package/dist/plugins/file-run-store.d.ts +90 -0
  317. package/dist/plugins/file-run-store.js +145 -13
  318. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  319. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  320. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  321. package/dist/plugins/file-workflow-journal-store.js +10 -0
  322. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  323. package/dist/plugins/fork-routing-session-store.js +51 -3
  324. package/dist/plugins/host-platform.d.ts +69 -0
  325. package/dist/plugins/host-platform.js +81 -2
  326. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  327. package/dist/plugins/image-bake-store-sql.js +241 -7
  328. package/dist/plugins/image-index-sql.d.ts +46 -0
  329. package/dist/plugins/image-index-sql.js +113 -4
  330. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  331. package/dist/plugins/k8s-bg-scripts.js +88 -4
  332. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  333. package/dist/plugins/k8s-exec-protocol.js +41 -0
  334. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  335. package/dist/plugins/local-checkpoint-store.js +86 -7
  336. package/dist/plugins/local-session-store.d.ts +157 -0
  337. package/dist/plugins/local-session-store.js +289 -34
  338. package/dist/plugins/local-task-attachment-store.js +14 -2
  339. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  340. package/dist/plugins/mailbox-store-sql.js +39 -6
  341. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  342. package/dist/plugins/memory-engine-pg.js +122 -4
  343. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  344. package/dist/plugins/memory-engine-tidb.js +115 -5
  345. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  346. package/dist/plugins/memory-engine-vector-util.js +5 -0
  347. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  348. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  349. package/dist/plugins/memory-run-store.d.ts +63 -0
  350. package/dist/plugins/memory-run-store.js +73 -8
  351. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  352. package/dist/plugins/memory-session-policy-store.js +17 -0
  353. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  354. package/dist/plugins/memory-sync-store-pg.js +45 -2
  355. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  356. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  357. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  358. package/dist/plugins/outcome-ledger-sql.js +97 -3
  359. package/dist/plugins/pg-approval-store.d.ts +7 -0
  360. package/dist/plugins/pg-approval-store.js +7 -0
  361. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  362. package/dist/plugins/pg-breaker-state.js +6 -0
  363. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  364. package/dist/plugins/pg-checkpoint-store.js +8 -0
  365. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  366. package/dist/plugins/pg-cost-quota.js +6 -0
  367. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  368. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  369. package/dist/plugins/pg-image-bake.d.ts +9 -0
  370. package/dist/plugins/pg-image-bake.js +9 -0
  371. package/dist/plugins/pg-image-index.d.ts +9 -0
  372. package/dist/plugins/pg-image-index.js +9 -0
  373. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  374. package/dist/plugins/pg-outcome-ledger.js +9 -0
  375. package/dist/plugins/pg-pool.d.ts +50 -0
  376. package/dist/plugins/pg-pool.js +78 -0
  377. package/dist/plugins/pg-query.d.ts +11 -0
  378. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  379. package/dist/plugins/pg-rate-limiter.js +12 -2
  380. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  381. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  382. package/dist/plugins/pg-run-store.d.ts +7 -0
  383. package/dist/plugins/pg-run-store.js +7 -0
  384. package/dist/plugins/pg-safe-json.d.ts +13 -0
  385. package/dist/plugins/pg-safe-json.js +40 -4
  386. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  387. package/dist/plugins/pg-session-policy-store.js +5 -0
  388. package/dist/plugins/pg-session-storage.d.ts +72 -0
  389. package/dist/plugins/pg-session-storage.js +152 -20
  390. package/dist/plugins/pg-session-store.d.ts +10 -0
  391. package/dist/plugins/pg-session-store.js +10 -0
  392. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  393. package/dist/plugins/pg-tool-result-store.js +7 -0
  394. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  395. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  396. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  397. package/dist/plugins/pg-workflow-run-store.js +7 -0
  398. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  399. package/dist/plugins/posix-shell-fs.js +31 -1
  400. package/dist/plugins/remote-env-adb.d.ts +25 -0
  401. package/dist/plugins/remote-env-adb.js +95 -12
  402. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  403. package/dist/plugins/remote-env-e2b.js +371 -40
  404. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  405. package/dist/plugins/remote-env-file-error.js +37 -0
  406. package/dist/plugins/remote-env-host.d.ts +151 -0
  407. package/dist/plugins/remote-env-host.js +468 -70
  408. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  409. package/dist/plugins/remote-env-k8s.js +318 -32
  410. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  411. package/dist/plugins/remote-env-local-docker.js +149 -24
  412. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  413. package/dist/plugins/remote-env-ssh.js +117 -20
  414. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  415. package/dist/plugins/remote-scratchpad.js +32 -2
  416. package/dist/plugins/remote-shell.d.ts +22 -0
  417. package/dist/plugins/remote-shell.js +27 -1
  418. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  419. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  420. package/dist/plugins/roster-store-sql.d.ts +27 -0
  421. package/dist/plugins/roster-store-sql.js +54 -0
  422. package/dist/plugins/run-store-sql.d.ts +194 -0
  423. package/dist/plugins/run-store-sql.js +210 -9
  424. package/dist/plugins/s3-presign.d.ts +20 -0
  425. package/dist/plugins/s3-presign.js +49 -2
  426. package/dist/plugins/scheduler-support.d.ts +12 -0
  427. package/dist/plugins/scheduler-support.js +75 -3
  428. package/dist/plugins/send-file-ledger.d.ts +15 -0
  429. package/dist/plugins/send-file-ledger.js +53 -4
  430. package/dist/plugins/send-user-file.d.ts +77 -0
  431. package/dist/plugins/send-user-file.js +92 -4
  432. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  433. package/dist/plugins/session-policy-store-sql.js +75 -3
  434. package/dist/plugins/session-store.d.ts +45 -0
  435. package/dist/plugins/session-store.js +51 -0
  436. package/dist/plugins/sql-driver.d.ts +77 -0
  437. package/dist/plugins/sql-driver.js +4 -0
  438. package/dist/plugins/sql-escape.d.ts +8 -0
  439. package/dist/plugins/sql-escape.js +8 -0
  440. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  441. package/dist/plugins/sql-row-helpers.js +25 -0
  442. package/dist/plugins/store-backend.d.ts +103 -0
  443. package/dist/plugins/store-backend.js +120 -27
  444. package/dist/plugins/store-contracts.d.ts +62 -0
  445. package/dist/plugins/store-contracts.js +3 -0
  446. package/dist/plugins/task-attachment-store.d.ts +60 -0
  447. package/dist/plugins/task-attachment-store.js +49 -3
  448. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  449. package/dist/plugins/task-list-store-sql.js +21 -0
  450. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  451. package/dist/plugins/tidb-approval-store.js +6 -0
  452. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  453. package/dist/plugins/tidb-breaker-state.js +5 -0
  454. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  455. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  456. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  457. package/dist/plugins/tidb-cost-quota.js +1 -0
  458. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  459. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  460. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  461. package/dist/plugins/tidb-image-bake.js +8 -0
  462. package/dist/plugins/tidb-image-index.d.ts +8 -0
  463. package/dist/plugins/tidb-image-index.js +8 -0
  464. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  465. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  466. package/dist/plugins/tidb-pool.d.ts +56 -0
  467. package/dist/plugins/tidb-pool.js +181 -1
  468. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  469. package/dist/plugins/tidb-rate-limiter.js +5 -2
  470. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  471. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  472. package/dist/plugins/tidb-run-store.d.ts +7 -0
  473. package/dist/plugins/tidb-run-store.js +7 -0
  474. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  475. package/dist/plugins/tidb-session-policy-store.js +5 -0
  476. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  477. package/dist/plugins/tidb-session-storage.js +62 -3
  478. package/dist/plugins/tidb-session-store.d.ts +142 -0
  479. package/dist/plugins/tidb-session-store.js +264 -16
  480. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  481. package/dist/plugins/tidb-tool-result-store.js +7 -0
  482. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  483. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  484. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  485. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  486. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  487. package/dist/plugins/tool-result-store-sql.js +38 -2
  488. package/dist/plugins/web-search.d.ts +35 -0
  489. package/dist/plugins/web-search.js +45 -9
  490. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  491. package/dist/plugins/workflow-journal-limits.js +10 -0
  492. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  493. package/dist/plugins/workflow-journal-store-sql.js +58 -2
  494. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  495. package/dist/plugins/workflow-run-store-sql.js +84 -6
  496. package/dist/plugins/worktree-isolation.d.ts +45 -0
  497. package/dist/plugins/worktree-isolation.js +105 -6
  498. package/dist/plugins/write-behind-counter.d.ts +56 -1
  499. package/dist/plugins/write-behind-counter.js +53 -14
  500. package/dist/principal-jwt.d.ts +24 -0
  501. package/dist/principal-jwt.js +60 -5
  502. package/dist/project-memory.d.ts +22 -0
  503. package/dist/project-memory.js +144 -15
  504. package/dist/prompts-domain-validate.d.ts +28 -0
  505. package/dist/prompts-domain-validate.js +42 -1
  506. package/dist/question.d.ts +33 -0
  507. package/dist/question.js +69 -2
  508. package/dist/resource-suspend.d.ts +21 -0
  509. package/dist/resource-suspend.js +16 -0
  510. package/dist/router/route-orchestration.d.ts +78 -0
  511. package/dist/router/route-orchestration.js +77 -0
  512. package/dist/run-local.d.ts +32 -0
  513. package/dist/run-local.js +172 -8
  514. package/dist/runs.d.ts +189 -4
  515. package/dist/runs.js +465 -24
  516. package/dist/runtime-caps-resolver.d.ts +106 -0
  517. package/dist/runtime-caps-resolver.js +89 -4
  518. package/dist/runtime-governance.d.ts +84 -0
  519. package/dist/runtime-governance.js +127 -1
  520. package/dist/sandbox-pkg-source.d.ts +23 -0
  521. package/dist/sandbox-pkg-source.js +37 -0
  522. package/dist/sealed-key.d.ts +54 -0
  523. package/dist/sealed-key.js +68 -3
  524. package/dist/security.d.ts +108 -0
  525. package/dist/security.js +145 -6
  526. package/dist/sema-registry.d.ts +21 -0
  527. package/dist/sema-registry.js +21 -0
  528. package/dist/session-leaf-bus.d.ts +31 -0
  529. package/dist/session-leaf-bus.js +32 -0
  530. package/dist/session-sync-content.d.ts +46 -0
  531. package/dist/session-sync-content.js +47 -1
  532. package/dist/session-sync-kernel.d.ts +89 -0
  533. package/dist/session-sync-kernel.js +48 -3
  534. package/dist/session-sync.d.ts +125 -0
  535. package/dist/session-sync.js +181 -8
  536. package/dist/session-titler.d.ts +26 -0
  537. package/dist/session-titler.js +41 -7
  538. package/dist/session-watch.d.ts +53 -1
  539. package/dist/session-watch.js +73 -9
  540. package/dist/sighup-idle.d.ts +30 -0
  541. package/dist/sighup-idle.js +12 -1
  542. package/dist/spec-fields.d.ts +91 -3
  543. package/dist/spec-fields.js +116 -4
  544. package/dist/task-cwd.d.ts +50 -0
  545. package/dist/task-cwd.js +68 -1
  546. package/dist/task-mcp.d.ts +47 -0
  547. package/dist/task-mcp.js +29 -0
  548. package/dist/task-settings.d.ts +175 -0
  549. package/dist/task-settings.js +226 -11
  550. package/dist/task-workflow.d.ts +67 -0
  551. package/dist/task-workflow.js +75 -8
  552. package/dist/tool-approval.d.ts +91 -0
  553. package/dist/tool-approval.js +215 -0
  554. package/dist/trace/artifacts.d.ts +9 -0
  555. package/dist/trace/artifacts.js +30 -5
  556. package/dist/trace/core-keyset-guard.d.ts +18 -0
  557. package/dist/trace/ledger-sink.d.ts +43 -0
  558. package/dist/trace/ledger-sink.js +64 -5
  559. package/dist/trace/project.d.ts +133 -0
  560. package/dist/trace/project.js +189 -2
  561. package/dist/trace/redact.d.ts +19 -0
  562. package/dist/trace/redact.js +66 -9
  563. package/dist/usage-analytics.d.ts +26 -0
  564. package/dist/usage-analytics.js +26 -3
  565. package/package.json +1 -1
@@ -1,3 +1,16 @@
1
+ /**
2
+ * v2 MVP M4 — leader endpoint wiring (V2-MVP-PLAN.md). `createLeaderRunner` turns a LeaderRequestBody into a
3
+ * `runLeaderTask` invocation with REAL deps: per-worker E2B envs (leader-owned, static so they outlive the
4
+ * task for diff-out) + a real ephemeral E2B integration sandbox + the Coordinator's credentialed
5
+ * `git push --force-with-lease`. This is the productization of the joint dogfood (which validated the exact
6
+ * logic on real infra) — gated behind LEADER_ENABLED (default off).
7
+ *
8
+ * 🔴 DEPLOY REQUIREMENTS (document — not satisfied by the default bun-slim image): the control plane (service
9
+ * host) needs **git** on PATH for the Coordinator clone/apply/push, plus a reachable durable remote +
10
+ * write creds (LEADER_GIT_TOKEN). E2B workers need outbound net only if the base repo is cloned over the
11
+ * network; the MVP seeds the base from the Coordinator (no worker→remote net). MVP Planner = caller-provided
12
+ * `subtasks` (an LLM DAG-planner is a follow-up).
13
+ */
1
14
  import { execFileSync } from "node:child_process";
2
15
  import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
16
  import { join } from "node:path";
@@ -11,6 +24,12 @@ import { pullDiff, safeRev } from "./diffout.js";
11
24
  import { runLeaderTask } from "./leader.js";
12
25
  import { attachRepairLoopDeps } from "./repair-wire.js";
13
26
  import { routePlanWithFallback, validateSubtasks } from "./planner.js";
27
+ /** The single-agent `runRepairLoop` is now WIRED LIVE (the canary-enable slice): when `LEADER_REPAIR_LOOP=true`
28
+ * the wire provisions a DEDICATED oracle-seeded grader sandbox per solo worker and attaches a real async
29
+ * `resolve` to `attachRepairLoopDeps` (below). With this `true`, flipping `LEADER_REPAIR_LOOP` engages BOTH the
30
+ * repair loop AND the §10.5 resource-suspend mutual exclusion (a repair-owned worker never resource-suspends).
31
+ * Still OFF-by-default — with the flag off, `resolve` is undefined → `attachRepairLoopDeps` is a no-op → the
32
+ * default single-agent path is byte-identical to today. */
14
33
  const REPAIR_LOOP_WIRED = true;
15
34
  const sh = (env) => async (cmd) => {
16
35
  const r = await env.exec(`bash -lc ${JSON.stringify(cmd)}`);
@@ -28,30 +47,77 @@ const asIntegrationEnv = (env) => ({
28
47
  writeFile: async (p, c) => { const r = await env.writeFile(p, c); if (!r.ok)
29
48
  throw r.error; },
30
49
  });
50
+ /**
51
+ * Resume-safe worker staging (the design/68 F2(a) factory-env path). Runs adapter-side before the agent's
52
+ * first workspace-touching call: seed the base repo at the worker branch + plant the upload script (so the
53
+ * presigned URL never passes through the model).
54
+ *
55
+ * 🔴 BL-1 fix (design/74 Slice 6): on a RESOURCE-SUSPEND RESUME core re-invokes the `executionEnvFactory`,
56
+ * producing a FRESH `withStaging` wrapper (`staged=undefined`) whose `stage()` runs AGAIN — AFTER core's
57
+ * `resumeVM()` has already untar'd the snapshot onto the fresh pod (`resumeVM` is not a STAGED_METHOD, so it
58
+ * is NOT intercepted by the staging proxy; the agent's first `exec` is what triggers `stage()`, lazily, and
59
+ * by then the snapshot is restored). The old `stage()` ran the seed UNCONDITIONALLY:
60
+ * `${seedCmd}; cd ${repo}; git checkout -q -b ${branch}`
61
+ * and `seedCmd` begins with `rm -rf /workspace/repo` — so it WIPED the just-restored snapshot and re-seeded at
62
+ * `baseSha`, then created the worker branch at base. The forensic proof (leaderRunId 019ecda7): the suspend
63
+ * snapshot object DID contain the worker's commit (`git log` in the S3 tarball = the real progress), yet every
64
+ * resumed slice's `git log` showed only the base commit — the worker rebuilt destroyed work for ~47 min. THIS
65
+ * (a staging re-seed clobbering a correctly-restored snapshot) is the dominant cause of failed make-real runs.
66
+ *
67
+ * The fix = a RESTORED-SNAPSHOT SENTINEL that no-ops staging on resume. The robust signal is the upload-script
68
+ * MARKER FILE (`uploadScriptPath`): staging itself plants it, so it is present in EVERY restored snapshot
69
+ * (verified: it survives in both a base-state in-progress snapshot AND a post-commit one) and ABSENT on a
70
+ * genuinely fresh pod — and it is INDEPENDENT of git/commit state. That last point matters: a worker can
71
+ * suspend with work in progress but no commit yet (HEAD still == baseSha), so a "HEAD advanced past baseSha"
72
+ * probe alone would WRONGLY re-seed+clobber that valid snapshot. The marker captures "staging already ran here"
73
+ * regardless of whether a commit landed. We additionally accept the worker branch already existing as a
74
+ * secondary restored-snapshot signal (belt-and-suspenders for the same git-state-independent reason).
75
+ *
76
+ * A FRESH pod has neither marker nor branch → full staging runs. A probe transport failure falls through to
77
+ * full staging too (fails honestly via `sh()`, never silently skips). `branch`/paths are `validateSubtasks`-
78
+ * clean / deployment config and are JSON-quoted under `bash -lc` regardless. Exported for the regression test.
79
+ */
31
80
  export async function stageWorkerEnv(env, opts) {
32
81
  const { seedCmd, repo, branch, uploadScriptPath, uploadScript } = opts;
82
+ // Restored-snapshot sentinel (non-throwing exec — we need the exit code, not an exception). Two independent
83
+ // signals, EITHER of which proves "staging already ran here, this is a resumed snapshot, do NOT re-seed":
84
+ // (1) the upload-script marker file is present — the definitive signal (planted by staging, git-state
85
+ // independent, so it covers an in-progress-but-uncommitted snapshot where HEAD is still at base); and
86
+ // (2) the worker branch already exists — secondary, also git-state independent.
87
+ // Both probed in ONE round-trip; exit 0 ⇒ restored snapshot ⇒ NO-OP (never `rm -rf` the restored workspace).
88
+ // A transport failure ({ok:false}) falls through to full staging (honest fail via sh()), never silent-skips.
33
89
  const probe = await env.exec(`bash -lc ${JSON.stringify(`if [ -f ${uploadScriptPath} ]; then exit 0; fi; ` +
34
90
  `cd ${repo} 2>/dev/null && git rev-parse --verify --quiet refs/heads/${branch} >/dev/null && exit 0; ` +
35
91
  `exit 1`)}`);
36
92
  if (probe.ok && probe.value.exitCode === 0)
37
- return;
93
+ return; // resume — repo/branch/upload-script already in the snapshot
38
94
  await sh(env)(`${seedCmd}; cd ${repo}; git checkout -q -b ${branch}`);
39
95
  const wr = await env.writeFile(uploadScriptPath, uploadScript);
40
96
  if (!wr.ok)
41
97
  throw new Error(`upload-script staging failed: ${wr.error.message}`);
42
98
  }
99
+ /** Build the `runLeader(body)` the HTTP endpoint invokes. Constructs real per-task deps + runs the leader. */
100
+ /**
101
+ * Per-leader-run resource bounds derived from env (2026-06-14). Exported for unit tests. The worker sandbox
102
+ * lifetime (BUG2), the worker's diff-upload presigned-URL TTL (BUG1), and the worker spec's triple bound
103
+ * (maxTurns/timeoutSec/maxCostUsd, #15) ALL track one `leaderTimeoutMs` — a hardcoded 10min (sandbox) or 1h
104
+ * (URL) silently killed long autonomous builds or expired the diff upload mid-run. core's turn cap is now a
105
+ * high net (10000), so the leader gives each worker an explicit triple bound; a sub-task's own limits override.
106
+ */
43
107
  export function leaderResourceConfig(env = process.env) {
44
- const leaderTimeoutMs = Math.max(600_000, Math.floor(Number(env.LEADER_TIMEOUT_MS ?? "0")) || 86_400_000);
108
+ const leaderTimeoutMs = Math.max(600_000, Math.floor(Number(env.LEADER_TIMEOUT_MS ?? "0")) || 86_400_000); // default 24h (was 10min)
45
109
  const workerMaxTurns = Math.floor(Number(env.LEADER_WORKER_MAX_TURNS ?? "0")) || 10_000;
46
110
  const workerBudgetUsd = Number(env.LEADER_WORKER_BUDGET_USD ?? "0") || 100;
47
111
  const resourceSuspendOn = String(env.LEADER_RESOURCE_SUSPEND ?? "").toLowerCase() === "true";
112
+ // Per-slice window: a fraction of the total so a worker suspends+resumes several times across its budget
113
+ // (default = total/4, min $1). Smaller window ⇒ more, shorter slices ⇒ progress saved more often.
48
114
  const sliceMaxCostUsd = Number(env.LEADER_WORKER_SLICE_BUDGET_USD ?? "0") || Math.max(1, workerBudgetUsd / 4);
49
115
  return {
50
116
  leaderTimeoutMs,
51
117
  workerMaxTurns,
52
118
  workerBudgetUsd,
53
119
  workerLimits: { limits: { maxTurns: workerMaxTurns, timeoutSec: Math.floor(leaderTimeoutMs / 1000) }, maxCostUsd: workerBudgetUsd },
54
- presignTtlSec: Math.ceil(leaderTimeoutMs / 1000) + 600,
120
+ presignTtlSec: Math.ceil(leaderTimeoutMs / 1000) + 600, // URL/sandbox must outlive the worker (BUG1/BUG2)
55
121
  ...(resourceSuspendOn
56
122
  ? {
57
123
  resourceSuspend: {
@@ -71,23 +137,42 @@ export function createLeaderRunner(cfg) {
71
137
  const repairRounds = Math.max(0, Math.floor(Number(process.env.LEADER_REPAIR_ROUNDS ?? cfg.repairRounds ?? 0)) || 0);
72
138
  const repairBudgetUsd = Number(process.env.LEADER_REPAIR_BUDGET_USD ?? "4") || 4;
73
139
  const conflictRounds = Math.max(0, Math.floor(Number(process.env.LEADER_CONFLICT_ROUNDS ?? cfg.conflictRounds ?? 0)) || 0);
140
+ // ── LEADER-REPAIRLOOP-INTEGRATION §10 env knobs (FRESH hunk, §10.8 — mirrors LEADER_REPAIR_ROUNDS above) ──
141
+ // Every flag default-OFF so the whole feature is inert until flipped on a canary (the default path is
142
+ // byte-identical to today). `LEADER_REPAIR_LOOP` is the MASTER (gates the single-agent `runRepairLoop` dep);
143
+ // `LEADER_MEASURE_GATES` gates the merge push-hold-on-signal + measure-drives-repair (§10.3/§10.4);
144
+ // `LEADER_REPAIR_LOOP_ATTEMPTS` is the in-loop attempt ceiling (validated 2-3, default 2 — design/78 §5);
145
+ // `LEADER_ORACLE_FLAKY_K` is the flaky-settle re-isolation count (default 2 — §10.1 / repair-oracle.ts).
74
146
  const repairLoopOn = String(process.env.LEADER_REPAIR_LOOP ?? "").toLowerCase() === "true";
75
147
  const measureGatesOn = String(process.env.LEADER_MEASURE_GATES ?? "").toLowerCase() === "true";
76
148
  const repairLoopAttempts = Math.min(3, Math.max(2, Math.floor(Number(process.env.LEADER_REPAIR_LOOP_ATTEMPTS ?? "2")) || 2));
77
149
  const oracleFlakyK = Math.max(1, Math.floor(Number(process.env.LEADER_ORACLE_FLAKY_K ?? "2")) || 2);
150
+ // worker resource bounds (limits/maxCostUsd) + presign ttl are derived in leaderResourceConfig(), above.
151
+ // Bounded integration-repair (search 2026-06-14): when the merged tree compiles-clean-but-fails, run a strong
152
+ // agent WITH HANDS in the live merged sandbox to fix the cross-worker integration, then mergeBranches re-runs
153
+ // testCmd. OFF unless LEADER_REPAIR_ROUNDS>0 — closes over the RAW env (hands need the real RemoteExecutionEnv,
154
+ // not the exec/writeFile-only IntegrationEnv wrapper). Strong model (default role); no durable wiring (short).
78
155
  const mkRepair = (rawEnv, repoDir, oracleFiles) => {
79
156
  if (repairRounds <= 0)
80
157
  return undefined;
81
158
  return {
82
159
  maxRounds: repairRounds,
83
160
  run: async ({ round, errorText, testCmd }) => {
161
+ // 🔴 Measurement integrity (council blocker + partner-Codex gotcha): HIDE the hidden oracle so the repair
162
+ // agent (rooted at the repo) can't `cat` the test it's graded on and cheat; RE-INJECT it in `finally` so
163
+ // merge's re-test gate verifies the fix against the real oracle (and it's hidden again next round).
84
164
  for (const f of oracleFiles) {
85
- await rawEnv.remove(f.path).catch(() => { });
165
+ await rawEnv.remove(f.path).catch(() => { }); // best-effort delete (may be absent)
166
+ // FAIL-CLOSED (partner-Codex): remove() returns a Result that does NOT throw on failure, so a silent
167
+ // {ok:false} would leave the oracle readable and the repair model could `cat` it. VERIFY it's gone.
86
168
  const ex = await rawEnv.exists(f.path);
87
169
  if (ex.ok && ex.value)
88
170
  throw new Error(`oracle still present after remove (${f.path}) — refusing repair (measurement integrity)`);
89
171
  }
90
172
  try {
173
+ // rootPath: repoDir (Codex review #4) — without it core roots the file tools at executionEnv.cwd
174
+ // (/workspace on Kata), one level above the repo (/workspace/repo). bash can cd, but the dedicated
175
+ // read/edit tools would start too high + lose containment.
91
176
  const runner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing, executionEnv: rawEnv, rootPath: repoDir });
92
177
  const objective = [
93
178
  `The integrated project at ${repoDir} fails its build/test. Make the MINIMAL change to the working tree so this command exits 0 (cd into the repo and run it yourself to confirm):`,
@@ -95,6 +180,8 @@ export function createLeaderRunner(cfg) {
95
180
  `Several agents each ported a DISJOINT module group; the failure is almost certainly a cross-module integration mismatch (a shared interface, a missing/renamed symbol, a type/signature disagreement between two groups). Read the failing files, fix the smallest set of files, and re-run the command to verify it passes.`,
96
181
  `HARD RULES: do NOT git commit or git push; do NOT modify build configuration (gradle.properties / AGP / dependency versions / settings); do NOT add build-tooling files; do NOT call AskUserQuestion — decide autonomously. Preserve the ported semantics — fix the integration, never delete behavior just to make it pass.`,
97
182
  ``,
183
+ // BL-32 — the failing output is worker/build-authored; delimit it so an injected instruction in a stack
184
+ // trace / test message can't steer the repair agent (design/53 trifecta).
98
185
  delimitUntrusted("FAILING OUTPUT (untrusted)", errorText),
99
186
  ].join("\n");
100
187
  const res = await runner
@@ -105,11 +192,16 @@ export function createLeaderRunner(cfg) {
105
192
  limits: { timeoutSec: Math.max(300, Math.floor(leaderTimeoutMs / 1000 / 2)) },
106
193
  })
107
194
  .result();
195
+ // A non-completed repair (timeout/abort) may leave a process alive in the SAME Kata pod that would race
196
+ // the merge re-test (Codex review #1) — surface it as a throw so mergeBranches does NOT re-test: it keeps
197
+ // the original failure and the `finally` destroys the sandbox, killing any orphan.
108
198
  if (res.status !== "completed")
109
199
  throw new Error(`repair round ${round} did not complete (status=${res.status})`);
110
200
  return { costUsd: res.stats?.costMicroUsd !== undefined ? res.stats.costMicroUsd / 1e6 : undefined, note: res.result?.slice(0, 200) };
111
201
  }
112
202
  finally {
203
+ // Re-inject the oracle so merge's re-test gate (run right after) verifies the fix against the REAL hidden
204
+ // test — even if the repair model threw. It's hidden again at the top of the next round.
113
205
  for (const f of oracleFiles) {
114
206
  const wr = await rawEnv.writeFile(f.path, f.content);
115
207
  if (!wr.ok)
@@ -119,6 +211,12 @@ export function createLeaderRunner(cfg) {
119
211
  },
120
212
  };
121
213
  };
214
+ // Bounded merge-conflict resolution (search 2026-06-16): a `git apply --3way` conflict means two workers touched
215
+ // overlapping lines. Instead of the leader discarding ALL fan-out work + redoing single (collapseToSingle), run a
216
+ // strong agent WITH HANDS in the conflicted sandbox to integrate the conflicting worker's patch (the others
217
+ // already applied clean). OFF unless LEADER_CONFLICT_ROUNDS>0. Mirrors mkRepair: raw env for hands; hide the
218
+ // hidden oracle so the resolver can't grade-peek; restore in `finally` so the downstream test gate sees the real
219
+ // oracle. mergeBranches re-checks for leftover markers/.rej and degrades to collapse if the resolution is unclean.
122
220
  const mkConflictResolver = (rawEnv, repoDir, oracleFiles) => {
123
221
  if (conflictRounds <= 0)
124
222
  return undefined;
@@ -139,6 +237,8 @@ export function createLeaderRunner(cfg) {
139
237
  `When done, NO conflict markers and NO *.rej files may remain under ${repoDir}. Verify yourself before finishing: grep -rIlE '^(<<<<<<<|>>>>>>>)' . ; find . -name '*.rej' — BOTH must print nothing.`,
140
238
  `HARD RULES: do NOT git commit / git add / git push (the coordinator squashes at the end); do NOT modify build configuration; do NOT call AskUserQuestion — decide autonomously. Preserve both sides' ported semantics.`,
141
239
  ``,
240
+ // BL-32 — the worker patch + conflict text are untrusted worker-adjacent content; delimit both so an
241
+ // injected instruction can't steer the conflict-resolver agent (design/53 trifecta).
142
242
  delimitUntrusted("CONFLICTING WORKER PATCH (untrusted)", patch.slice(0, 6000)),
143
243
  delimitUntrusted("CONFLICT DETAILS (untrusted)", conflictText),
144
244
  ].join("\n");
@@ -169,12 +269,22 @@ export function createLeaderRunner(cfg) {
169
269
  if (!body.objective || !body.durableRemote || !body.testCmd || !body.seedCmd || !body.baseSha) {
170
270
  return { ok: false, reports: [], cancelled: false, error: "request must provide objective, durableRemote, baseSha, testCmd, seedCmd" };
171
271
  }
272
+ // `durableRemote` is handed to `git clone` on the CONTROL PLANE (with the Coordinator's creds). git executes
273
+ // transport-helper URLs (`ext::sh -c '…'`, `file://…`) as commands, so allow only a normal http(s)/git/ssh
274
+ // URL or an scp-style user@host:path — reject the transport-helper class even though the caller is trusted.
172
275
  if (!/^(?:https?|git|ssh):\/\/[^\s]+$/i.test(body.durableRemote) && !/^[\w.-]+@[\w.-]+:[^\s]+$/.test(body.durableRemote)) {
173
276
  return { ok: false, reports: [], cancelled: false, error: "durableRemote must be an http(s)/git/ssh URL or user@host:path (no ext::/file:// transport helpers)" };
174
277
  }
278
+ // baseSha is interpolated into worker-shell lines on BOTH env paths (static: format-patch via pullDiff,
279
+ // which re-validates; factory: the staged upload script) — gate it here so the factory path is covered too.
175
280
  if (!safeRev(body.baseSha)) {
176
281
  return { ok: false, reports: [], cancelled: false, error: "baseSha must be a plain git rev (sha/branch token)" };
177
282
  }
283
+ // B-2: write the hidden oracle into the integration sandbox (workers never see it) + local-exclude it so the
284
+ // squash `git add -A` does NOT commit/push it into the durable integration branch (Codex review #1: else the
285
+ // hidden test leaks into the repo, visible to any future worker seeded from it). gradle compiles src/test
286
+ // regardless of git status, so the correctness gate still runs. NOTE: if integration-repair is enabled, the
287
+ // repair agent (rooted at the repo) could still READ the on-disk oracle — delete it before repair runs then.
178
288
  const injectOracles = async (env) => {
179
289
  const ofs = body.oracleFiles ?? [];
180
290
  if (ofs.length === 0)
@@ -184,6 +294,9 @@ export function createLeaderRunner(cfg) {
184
294
  if (!wr.ok)
185
295
  throw wr.error;
186
296
  }
297
+ // Local-exclude each oracle so `git add -A` never commits it (B-2 sandbox-only). Root-anchor with a leading
298
+ // "/" + escape a leading "#"/"!" so the path is a literal exclude, not a gitignore comment/negation (council
299
+ // #4). APPEND to (don't clobber) any seed-configured excludes — read the current file first (council #3).
187
300
  const anchor = (p) => "/" + (/^[#!]/.test(p) ? "\\" + p : p);
188
301
  const rel = ofs.map((f) => anchor(f.path.startsWith(`${repo}/`) ? f.path.slice(repo.length + 1) : f.path)).join("\n");
189
302
  const cur = await env.exec(`bash -lc ${JSON.stringify(`cat ${repo}/.git/info/exclude 2>/dev/null || true`)}`);
@@ -192,8 +305,18 @@ export function createLeaderRunner(cfg) {
192
305
  if (!ex.ok)
193
306
  throw ex.error;
194
307
  };
308
+ // design/158 A13: the four LeaderDeps methods below (plan/provisionWorker/provisionIntegrationSandbox/push)
309
+ // are named local functions — same closure scope, same capture, same execution order as when they were
310
+ // inline object-literal properties; only the "anonymous inline closure" form changed (behavior identical).
311
+ // caller-provided sub-tasks = an explicit FAN-OUT override; else the difficulty ROUTER decides (one model
312
+ // completion): default single (a 1-subtask plan) and only fan out when clearly+economically decomposable
313
+ // Either way → VALIDATED disjoint-file sub-tasks (planner.ts enforces the Coordinator's invariant).
195
314
  const plan = async () => {
196
315
  if (Array.isArray(body.subtasks) && body.subtasks.length > 0) {
316
+ // Validate caller-supplied sub-tasks through the SAME deterministic checks as an LLM plan — the
317
+ // branch is interpolated into a worker-container shell command (planner.validateSubtasks rejects a
318
+ // shell-unsafe branch / leading "-" / "..") and the disjoint-file + unique-id invariants are what
319
+ // the Coordinator's parallel merge relies on. Was a straight map() that skipped all of it.
197
320
  return validateSubtasks(body.subtasks);
198
321
  }
199
322
  const planRunner = new Runner({ brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing });
@@ -201,10 +324,14 @@ export function createLeaderRunner(cfg) {
201
324
  const res = await planRunner.runTaskStream({
202
325
  objective: prompt,
203
326
  sessionId: `leader-route-${Date.now()}`,
327
+ // Pin the route to a cheap classifier model (see `routerModel` doc): the heavy reasoning model
328
+ // returns an empty completion ~2/3 of the time on this prompt, collapsing every fan-out to single.
204
329
  ...(cfg.routerModel ? { model: cfg.routerModel } : {}),
205
330
  }).result();
206
331
  return res.result ?? "";
207
332
  };
333
+ // §5 quality gate: a rejected/unparseable plan retries the LLM ≤1, then collapses to single (B1-B3) —
334
+ // never plan-fails the task; the collapse reason is logged as a router-quality signal.
208
335
  const { subs, collapsed, rawSample } = await routePlanWithFallback(body.objective, runRoute, {
209
336
  ...(body.planContext ? { context: body.planContext } : {}),
210
337
  ...(cfg.fanoutEnabled === false ? { fanoutEnabled: false } : {}),
@@ -215,6 +342,9 @@ export function createLeaderRunner(cfg) {
215
342
  };
216
343
  const provisionWorker = async (sub) => {
217
344
  const sessionId = `leader-${sub.workerId}-${Date.now()}`;
345
+ // design/68 C4: durable suspend bits per worker task (mirrors main.ts's per-task wiring) — a gated
346
+ // ask/AskUserQuestion suspends the worker; ctx is seeded so the surfaced token resumes on the
347
+ // single-agent path (the resume body re-runs the sub-objective on this worker).
218
348
  let durableSpec = {};
219
349
  if (cfg.durable) {
220
350
  const d = cfg.durable;
@@ -228,7 +358,27 @@ export function createLeaderRunner(cfg) {
228
358
  cfg.logger?.warn?.("leader_putctx_failed", { workerId: sub.workerId, err: String(e) });
229
359
  });
230
360
  }
361
+ // design/74 Slice 6: opt-in resource-slice suspend. A worker that overruns its per-slice budget window
362
+ // SUSPENDS (resumable) instead of failing; the leader's runWorker auto-resumes until the TOTAL is spent.
363
+ // Reuses the durable checkpoint store (so requires `cfg.durable` for the store + durable tool-results +
364
+ // session — the same durable-resume prerequisites). The per-slice window OVERRIDES workerLimits.maxCostUsd
365
+ // (spread last); the total + cumulative spend ride on the checkpoint's resource ledger (core debits it).
231
366
  let resourceSpec = {};
367
+ // Slice-6 review BLOCKER: core's resource-suspend needs the FULL durable-resume prerequisites —
368
+ // a checkpoint store (cfg.durable), a durable tool-result store (cfg.toolResultStore; an in-memory
369
+ // offload makes core REFUSE to suspend), AND a durable session store (cfg.sessionStore; without it a
370
+ // resumed slice dies with SessionError "Entry <leafId> not found" — the worker's progress is lost,
371
+ // wire.ts:52-55). Require ALL THREE before applying the per-slice window: otherwise the worker's
372
+ // maxCostUsd would be cut to a quarter WITHOUT the ability to suspend/resume → it fails at 1/4 its
373
+ // budget with no warning. When opted in (resourceCfg) but a prerequisite is missing, leave the budget
374
+ // intact + warn (which one).
375
+ // §10.5 ENFORCED mutual exclusion: when the single-agent repair loop actually OWNS a worker, that worker
376
+ // must NOT also resource-suspend — the repair loop owns its attempt budget, and a resource-suspend mid-loop
377
+ // risks `attemptCount` corruption + budget overrun (§10.5: a doc aspiration is not enough, this drops
378
+ // `resourceSpec` by construction so the two are NEVER on the same spec). Gated on the loop being WIRED
379
+ // (`REPAIR_LOOP_WIRED=true` — the canary-enable slice attached a LIVE `resolveRepair`), so flipping
380
+ // `LEADER_REPAIR_LOOP` now engages BOTH the single-agent repair loop AND this resource-suspend exclusion for
381
+ // the worker the loop owns. (`REPAIR_LOOP_WIRED` is the live/inert switch — it shipped false pre-activation.)
232
382
  const repairLoopActive = repairLoopOn && REPAIR_LOOP_WIRED;
233
383
  if (repairLoopActive && resourceCfg) {
234
384
  cfg.logger?.warn?.("leader_resource_suspend_disabled_for_repair_loop", { workerId: sub.workerId, reason: "LEADER_REPAIR_LOOP active — resource-suspend mutually exclusive with the repair loop (§10.5)" });
@@ -251,6 +401,12 @@ export function createLeaderRunner(cfg) {
251
401
  : "no durable session store",
252
402
  });
253
403
  }
404
+ // Keep the resume ctx warm for the WHOLE first leg (found live: task02b run1). putCtx stamps
405
+ // `updated_at` once at provision, but reapCtx GC's any ctx older than runStaleSec that has no pending
406
+ // checkpoint and no task_active claim — sub-workers hold no task_active row (that lock belongs to the
407
+ // HTTP submit path), so a leg longer than the reap cutoff lost its ctx and the post-suspend /decide
408
+ // died 409 "resume context missing". Refresh inside the run; once suspended, the pending checkpoint
409
+ // itself shields the ctx from the reaper, and after a terminal result the ctx ages out as designed.
254
410
  const keepCtxWarm = (runner) => {
255
411
  const d = cfg.durable;
256
412
  if (!d)
@@ -267,29 +423,53 @@ export function createLeaderRunner(cfg) {
267
423
  };
268
424
  return runner;
269
425
  };
426
+ // design/68 §8 F2(a) — factory-env worker + self-upload diff-out (preferred; static mode = compat below).
270
427
  if (cfg.s3 && cfg.envFactory) {
271
428
  const s3 = cfg.s3;
272
429
  const envFactory = cfg.envFactory;
273
- const baseSha = body.baseSha;
430
+ const baseSha = body.baseSha; // guarded non-empty at entry (narrowing is lost inside this closure)
274
431
  const seedCmd = body.seedCmd;
432
+ // workerId is validateSubtasks-clean ([A-Za-z0-9._-]+) → safe as a key segment; the presigner
433
+ // backstop-rejects traversal anyway. One object per worker per leader run; a repair re-run overwrites.
275
434
  const key = `${s3.keyPrefix ?? "leader-diff"}/${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}/${sub.workerId}.patch`;
435
+ // The presigned URL must outlive the worker: it self-uploads its diff at the END of its run, which
436
+ // can be the full leader deadline (24h). The old `Math.min(3600, …)` clamp expired mid-run for any
437
+ // worker > 1h → the upload 403'd and the diff (progress) was lost. Track the worker deadline + slack.
438
+ // (Codex: instant-signing at upload time, from the control plane, is the cleaner long-term fix.)
276
439
  const ttl = presignTtlSec;
277
440
  const base = { endpoint: s3.endpoint, bucket: s3.bucket, accessKey: s3.accessKey, secretKey: s3.secretKey, ...(s3.region ? { region: s3.region } : {}), key, expiresSec: ttl };
278
441
  const putUrl = presignS3Url({ ...base, method: "PUT" });
279
442
  const getUrl = presignS3Url({ ...base, method: "GET" });
280
443
  const script = buildUploadScript({ repoDir: repo, baseSha, putUrl, workDir: W });
444
+ // Staging runs adapter-side before the agent's first workspace call: seed the base repo at the worker
445
+ // branch + plant the upload script (the presigned URL never passes through the model).
446
+ // Resume-safe (BL-1): stageWorkerEnv no-ops on a resumed snapshot (worker branch already present)
447
+ // instead of re-running `git checkout -b` (which would fail "branch exists" and kill the resumed
448
+ // worker). Now load-bearing because the prod auto-resume landed (leader.ts non-verify path, 9a91c60).
281
449
  const stage = async (env) => {
282
450
  await stageWorkerEnv(env, { seedCmd, repo, branch: sub.branch, uploadScriptPath: `${W}/.leader-upload.sh`, uploadScript: script });
451
+ // #16 tail (search 2026-06-17): INCREMENTAL progress upload. The upload script is READ-ONLY git
452
+ // (format-patch base..HEAD — no add/commit/index write), so a background loop re-running it keeps the
453
+ // worker's fixed diff key at its latest COMMITTED progress. If the env HARD-CRASHES before its final /
454
+ // belt upload, salvage (fetchUploadedDiff) then recovers up to the last commit instead of losing all
455
+ // (run 019eca71's "4 commits vaporized" was exactly a failed worker that never uploaded). No git
456
+ // concurrency (read-only); the teardown belt upload stays authoritative (same key, complete diff).
457
+ // Fire-and-forget + NEVER awaited: the loop never exits, so staging must not block on it — whether the
458
+ // env's exec detaches or blocks, the loop RUNS either way and the dangling promise is reaped when the
459
+ // pod dies. Best-effort: a launch failure (no nohup, etc.) just falls back to today's end-only upload.
283
460
  void sh(env)(`nohup sh -c 'while true; do sleep 90; sh ${W}/.leader-upload.sh >/dev/null 2>&1 || true; done' </dev/null >/dev/null 2>&1 &`).catch(() => { });
284
461
  };
285
462
  return {
286
463
  workerId: sub.workerId, sessionId, branch: sub.branch,
287
- baseSha,
464
+ baseSha, // seedCmd reproduces the durable base — same sha for every worker
288
465
  runner: keepCtxWarm(new Runner({
289
466
  brain: cfg.brain, models: cfg.models, roles: cfg.roles, pricing: cfg.pricing,
290
467
  ...(cfg.toolResultStore ? { toolResultStore: cfg.toolResultStore } : {}),
291
468
  ...(cfg.sessionStore ? { sessionStore: cfg.sessionStore } : {}),
292
469
  executionEnvFactory: (ctx) => withStaging(envFactory(ctx), stage, async (e) => {
470
+ // Belt (task02b run6): workers that did the work but never `git commit`ed upload an EMPTY diff
471
+ // (diff-out is committed-state vs base) — auto-commit any uncommitted work first. No-op for a
472
+ // worker that committed properly; the commit identity marks belt-captured work for the reviewer.
293
473
  await sh(e)(`cd ${repo} && git add -A && git -c user.name='leader-belt' -c user.email='belt@leader' commit -qm 'belt: auto-commit uncommitted worker output' || true; sh ${W}/.leader-upload.sh`);
294
474
  }),
295
475
  })),
@@ -313,6 +493,8 @@ export function createLeaderRunner(cfg) {
313
493
  };
314
494
  };
315
495
  const provisionIntegrationSandbox = async () => {
496
+ // Factory lane (k8s or e2b): one fresh env from the service factory; lazy-connect — first exec
497
+ // provisions the pod/VM, destroy() reaps it. Static lane: the original explicit E2B env.
316
498
  if (cfg.envFactory) {
317
499
  const env = cfg.envFactory({ sessionId: `leader-integ-${Date.now()}` });
318
500
  try {
@@ -328,6 +510,8 @@ export function createLeaderRunner(cfg) {
328
510
  if (!cfg.e2bApiKey)
329
511
  throw new Error("leader wire: no envFactory and no e2bApiKey");
330
512
  const env = new RemoteContainerExecutionEnv({ apiKey: cfg.e2bApiKey, timeoutMs: leaderTimeoutMs });
513
+ // Once connected, the VM is billable — if seeding throws, destroy it HERE before propagating, otherwise
514
+ // mergeBranches never receives the `destroy` closure and the sandbox leaks until E2B's timeout reaps it.
331
515
  if (!(await env.connect()).ok) {
332
516
  await env.destroy().catch(() => { });
333
517
  throw new Error("integ connect failed");
@@ -343,7 +527,11 @@ export function createLeaderRunner(cfg) {
343
527
  return { env: asIntegrationEnv(env), destroy: () => env.destroy().then(() => { }), ...(mkRepair(env, repo, body.oracleFiles ?? []) ? { repair: mkRepair(env, repo, body.oracleFiles ?? []) } : {}), ...(mkConflictResolver(env, repo, body.oracleFiles ?? []) ? { conflictResolver: mkConflictResolver(env, repo, body.oracleFiles ?? []) } : {}) };
344
528
  };
345
529
  const push = async (integratedPatch, baseSha) => {
530
+ // Coordinator (control plane, creds): clone durable remote, apply integrated series, force-with-lease push.
531
+ // 🔴 requires `git` on the service host PATH (deploy req).
346
532
  const dir = mkdtempSync(join(tmpdir(), "leader-coord-"));
533
+ // Force C locale so the `raced` regex below matches git's (English) push-rejection messages regardless of
534
+ // the host locale — otherwise a translated message → regex miss → a real race mislabeled non-retryable (council #5).
347
535
  const gitEnv = { ...process.env, LC_ALL: "C" };
348
536
  try {
349
537
  execFileSync("git", ["clone", "-q", body.durableRemote, dir], { env: gitEnv });
@@ -353,12 +541,26 @@ export function createLeaderRunner(cfg) {
353
541
  execFileSync("git", ["-C", dir, "am", "--3way", ".leader.patch"], { env: gitEnv });
354
542
  rmSync(join(dir, ".leader.patch"));
355
543
  const ref = body.targetRef ?? "refs/heads/main";
544
+ // CAS against the TARGET ref's ACTUAL current tip (not baseSha). The old `=ref:baseSha` lease assumed
545
+ // the target ref already pointed at baseSha — but a FRESH ref (or one at any other commit) is never at
546
+ // baseSha, so the lease rejected EVERY such push and mislabeled it "raced" (found live: auto1 reached
547
+ // push after a clean 6-worker fan-out + green gradle, and failed only here). ls-remote gives the ref's
548
+ // current oid (empty = it doesn't exist yet) → lease against THAT, which still detects a real concurrent
549
+ // merge race (the ref moved since we read it) but lets a normal create/update through.
550
+ // Does the target ref already exist? (exact full-ref match; --refs drops peeled annotated-tag lines.)
356
551
  const ls = execFileSync("git", ["-C", dir, "ls-remote", "--refs", "origin", ref], { encoding: "utf8", env: gitEnv });
357
552
  const exists = ls.split("\n").some((l) => l.split("\t")[1] === ref);
358
553
  if (exists) {
554
+ // Existing ref → keep the original CAS against baseSha (detects a concurrent merge that moved the ref
555
+ // off the base this run started from — council#2). NOT against a just-read end-of-run tip: that would
556
+ // let leader B force-push over leader A's concurrent merge (Codex review #1). A ref that exists but
557
+ // isn't at baseSha → refuse (use a fresh per-run targetRef to avoid that — the proving-ground does).
359
558
  execFileSync("git", ["-C", dir, "push", `--force-with-lease=${ref}:${baseSha}`, "origin", `HEAD:${ref}`], { env: gitEnv });
360
559
  }
361
560
  else {
561
+ // Absent → create with a "must not exist" lease (empty expected oid): a concurrent create races safely
562
+ // (rejected as stale info) instead of silently fast-forwarding. The original `:baseSha` lease wrongly
563
+ // rejected a fresh ref (it's never at baseSha) — that was auto1's only failure after a green build.
362
564
  execFileSync("git", ["-C", dir, "push", `--force-with-lease=${ref}:`, "origin", `HEAD:${ref}`], { env: gitEnv });
363
565
  }
364
566
  return { ok: true, ref };
@@ -378,14 +580,39 @@ export function createLeaderRunner(cfg) {
378
580
  push,
379
581
  testCmd: body.testCmd,
380
582
  repoDir: repo, workerRepoDir: repo,
381
- timeoutMs: leaderTimeoutMs, maxConcurrency: 4,
583
+ // Per-wave fan-out deadline. LEADER_TIMEOUT_MS raises it (raise-only, parity with TASK_TIMEOUT_SEC —
584
+ // found live: task02b run5, porting workers + collapse-solo all 'run aborted' at the 600s default while
585
+ // mid-gradle; the per-worker presign ttl below tracks the same knob).
586
+ timeoutMs: leaderTimeoutMs, maxConcurrency: 4, // Semaphore cap; the planner emits ≤6 sub-tasks
587
+ // replan-lite (design/68 §6) always on in the wired leader; LEADER_BUDGET_USD bounds the fan-out spend.
382
588
  replan: { ...(process.env.LEADER_BUDGET_USD ? { budgetUsd: Number(process.env.LEADER_BUDGET_USD) } : {}) },
589
+ // LEADER-REPAIRLOOP-INTEGRATION §10.3 — the merge push-hold-on-signal (OFF unless LEADER_MEASURE_GATES). It
590
+ // needs NO extra sandbox: `strongOracleSeeded` keys on whether a hidden held-out oracle was injected into the
591
+ // integration sandbox (`injectOracles` runs `body.oracleFiles`), and the §10.3 hold combines it with the
592
+ // existing observe-only `measureCmd` result inside `mergeBranches`. §10.4's out-of-process measure grader
593
+ // (`measureDrivesRepair`) is a separate re-seedable sandbox — the canary-enable add-on (§6 step 5); it is
594
+ // intentionally NOT wired here in v1 (a half-mint would be a stopgap), so `measureGates` ships the §10.3
595
+ // signal-hold only. With LEADER_MEASURE_GATES off this whole block is absent → byte-identical merge path.
383
596
  ...(measureGatesOn
384
597
  ? { mergeGates: { measureGates: true, ...((body.oracleFiles?.length ?? 0) > 0 ? { strongOracleSeeded: true } : {}) } }
385
598
  : {}),
386
599
  ...(cfg.logger ? { logger: cfg.logger } : {}),
387
600
  };
601
+ // §10.8 — the SINGLE wire-call helper for the opt-in single-agent repair loop (LEADER_REPAIR_LOOP). The
602
+ // canary-enable slice attaches a LIVE async `resolve(solo, sub)` that, per solo worker, provisions a DEDICATED
603
+ // oracle-seeded GRADER sandbox (a SEPARATE sandbox from the worker + the integration sandbox — distinct object/
604
+ // sandboxId by construction, §10.2 structural isolation) and binds the per-worker diff source + the concrete
605
+ // Runner. OFF-by-default: `resolve` is attached ONLY when `repairLoopOn` (LEADER_REPAIR_LOOP=true); with the
606
+ // flag off `resolve` is undefined → `attachRepairLoopDeps` is a NO-OP → `deps.repairLoop` stays unset → the
607
+ // single-agent default path is byte-identical to today. The §10.6 push chokepoint (merge.ts) is LIVE
608
+ // regardless: once any report carries a `repairTerminal`, it holds.
609
+ //
610
+ // The grader is provisioned the SAME way as the integration sandbox (provisionIntegrationSandbox: raw env →
611
+ // seed → injectOracles → integBase), then exposed as a `GraderHandle` (the raw RemoteExecutionEnv IS an
612
+ // ExecutionEnv). `graderDestroy` reaps it in `runRepairLoopForLeader`'s `finally`. On a seed/inject throw the
613
+ // env is destroyed before propagating (mirrors provisionIntegrationSandbox :587-590 / :604-606).
388
614
  const resolveRepair = async (solo, _sub) => {
615
+ // Provision a DEDICATED grader: factory lane mints a fresh env (lazy-connect); static lane connects an E2B VM.
389
616
  let env;
390
617
  if (cfg.envFactory) {
391
618
  env = cfg.envFactory({ sessionId: `leader-grader-${Date.now()}` });
@@ -400,6 +627,8 @@ export function createLeaderRunner(cfg) {
400
627
  }
401
628
  env = e2b;
402
629
  }
630
+ // Seed the base repo + inject the hidden oracle ONLY in this grader (never the worker env). On a throw,
631
+ // destroy the billable env before propagating (else it leaks until the adapter's timeout reaps it).
403
632
  let integBase;
404
633
  try {
405
634
  await sh(env)(body.seedCmd);
@@ -417,20 +646,33 @@ export function createLeaderRunner(cfg) {
417
646
  repoDir: repo,
418
647
  integBase,
419
648
  };
649
+ // The worker diff source: factory lane = the worker's self-upload (`solo.fetchDiff`); static lane = pull the
650
+ // committed `base..HEAD` series straight out of the worker's still-alive env (the same merge `pullDiff` path).
420
651
  const workerRepoDir = repo;
421
652
  const pullWorkerDiff = solo.fetchDiff
422
- ?
653
+ ? // 🔴 BL-33 factory-lane residual: the self-upload path captures only what the fix turn UPLOADED; core's
654
+ // repairObjective carries no upload mandate, so an un-uploaded fix is missed. A deterministic belt needs
655
+ // a worker-env exec handle the factory lane does not surface (env-recording factory = follow-up). The
656
+ // fork2.1 stale-diff guard keeps this SAFE (no false candidate) until then.
423
657
  solo.fetchDiff
424
658
  : async () => {
659
+ // 🔴 BL-33 — the STATIC lane EXPOSES the worker env (`solo.diffEnv`), so deterministically belt-commit
660
+ // the worker's UNCOMMITTED fix-turn work BEFORE the committed-only `format-patch base..HEAD` pull —
661
+ // else attempts ≥2 grade a STALE diff (the fix never observed). Best-effort + only when there is a
662
+ // change to commit (no empty commits polluting the series). Mirrors the teardown belt, run per-grade.
425
663
  const wenv = solo.diffEnv;
426
664
  await wenv
427
665
  .exec(`bash -lc ${JSON.stringify(`cd ${repo} && git add -A && (git diff --cached --quiet || git -c user.email=w@w.co -c user.name=worker commit -q -m repair-wip)`)}`)
428
666
  .catch(() => { });
429
667
  return pullDiff(solo.diffEnv, solo.baseSha, { ref: solo.branch, ...(workerRepoDir ? { cwd: workerRepoDir } : {}) });
430
668
  };
669
+ // The trusted, spec-derived oracle steps (the integration testCmd) run in the grader; NEVER worker-authored.
431
670
  const oracleSteps = [{ command: body.testCmd, cwd: repo, label: "oracle-test" }];
671
+ // tier: a seeded hidden held-out oracle clears to `trusted_hidden`; a compile-only gate is `property_harness_weak`.
432
672
  const oracleFiles = body.oracleFiles ?? [];
433
673
  const passTier = oracleFiles.length > 0 ? "trusted_hidden" : "property_harness_weak";
674
+ // fork1.1 — make the INTENTIONAL factory-lane identity-check skip observable (distinct from an
675
+ // accidental workerEnv omission, which onWarn's generic MINOR-2 warning can't tell apart).
434
676
  if (solo.fetchDiff)
435
677
  cfg.logger?.info?.("repair_loop_factory_lane_isolation", { workerId: solo.workerId, reason: "identity check intentionally skipped — isolation by independent grader sandbox construction (§10.2)" });
436
678
  return {
@@ -440,9 +682,14 @@ export function createLeaderRunner(cfg) {
440
682
  pullWorkerDiff,
441
683
  oracleSteps,
442
684
  passTier,
685
+ // council 2026-06-17 — re-inject the seeded oracle after each hermetic reset (clean -fdx wipes it);
686
+ // fork1.2 — the paths a candidate patch must not touch (the oracle files' own paths).
443
687
  ...(oracleFiles.length > 0 ? { oracleFiles, oraclePaths: oracleFiles.map((f) => f.path) } : {}),
444
688
  maxAttempts: repairLoopAttempts,
445
689
  flakyK: oracleFlakyK,
690
+ // §10.2 — on the factory lane the worker's RAW env is not surfaced (only fetchDiff), so OMIT workerEnv
691
+ // (runRepairLoop skips the identity check; the grader is a separate sandbox by construction). On the static
692
+ // lane the leader owns the worker's RemoteExecutionEnv (`solo.diffEnv` is that env) → pass it so the check runs.
446
693
  ...(!solo.fetchDiff && solo.diffEnv ? { workerEnv: solo.diffEnv } : {}),
447
694
  log: (event, x) => event.includes("fail") || event.includes("warn") || event.includes("threw")
448
695
  ? cfg.logger?.warn?.(event, x)
@@ -1,8 +1,24 @@
1
+ /**
2
+ * Bridges WS ⇄ a language server's stdio. Server command from `LSP_CMD`, port `LSP_PORT`, and a per-session
3
+ * **auth token** `LSP_TOKEN` (the endpoint is a public `wss://<port>-<id>.e2b.app` URL — the runner connects with
4
+ * `?token=<secret>`; without it, anyone with the URL could read the workspace via LSP, council #4). Frame parsing
5
+ * uses the unit-tested {@link FRAME_DECODER_JS} (council #1/#2/#5).
6
+ */
1
7
  export declare const BRIDGE_SOURCE: string;
8
+ /** Language server command per languageId. P1 = typescript/javascript; dart/kotlin land with their template servers.
9
+ * `--stdio` only where the server needs it to pick stdio over its other transports (the node-based servers);
10
+ * gopls/jdtls/kotlin-language-server/sourcekit-lsp/`dart language-server` speak LSP over stdio by default. */
2
11
  export declare const SERVER_CMD: Readonly<Record<string, string>>;
12
+ /** npm packages a non-baked sandbox needs (on-the-fly install). Languages absent here (go) REQUIRE a baked template. */
3
13
  export declare const SERVER_NPM: Readonly<Record<string, string>>;
14
+ /** Bridge dir + port inside the sandbox. One bridge process per language → distinct ports. */
4
15
  export declare const BRIDGE_DIR = "/home/user/.lsp-bridge";
5
16
  export declare function portForLanguage(language: string): number;
17
+ /** FOREGROUND install (run via `env.exec` — must finish before the start). A baked template makes both checks
18
+ * skip instantly; a non-baked sandbox npm-installs the server + ws here (slow once per sandbox). */
6
19
  export declare function lspInstallCommand(language: string): string;
20
+ /** Start the bridge — run as a TRUE background command (`env.startBackground`), NOT `&`-backgrounded inside a
21
+ * foreground run: E2B reaps the foreground process group on completion, killing an in-shell `&`/nohup child.
22
+ * So node is the FOREGROUND here and E2B keeps the background command alive. */
7
23
  export declare function lspStartCommand(language: string, port: number, token: string): string;
8
24
  //# sourceMappingURL=e2b-bridge.d.ts.map