@sema-agent/server 1.322.0 → 2.0.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 (539) 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-reclaim.d.ts +19 -0
  46. package/dist/boot-reclaim.js +20 -0
  47. package/dist/brain.d.ts +25 -0
  48. package/dist/brain.js +61 -1
  49. package/dist/budget.d.ts +66 -0
  50. package/dist/budget.js +128 -4
  51. package/dist/capabilities/builtin-tools.d.ts +3 -0
  52. package/dist/capabilities/builtin-tools.js +3 -0
  53. package/dist/capabilities/center-plugins.d.ts +17 -1
  54. package/dist/capabilities/center-plugins.js +45 -4
  55. package/dist/capabilities/center-prompts.d.ts +46 -0
  56. package/dist/capabilities/center-prompts.js +57 -3
  57. package/dist/capabilities/code-review-council.d.ts +28 -0
  58. package/dist/capabilities/code-review-council.js +40 -7
  59. package/dist/capabilities/collab-wire.d.ts +2 -0
  60. package/dist/capabilities/collab-workflows.d.ts +7 -0
  61. package/dist/capabilities/collab-workflows.js +44 -1
  62. package/dist/capabilities/oa-tools.d.ts +6 -0
  63. package/dist/capabilities/oa-tools.js +10 -0
  64. package/dist/capabilities/prompt.d.ts +14 -0
  65. package/dist/capabilities/prompt.js +14 -0
  66. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  67. package/dist/capabilities/prompts/code-review.js +14 -0
  68. package/dist/capabilities/prompts/identity.d.ts +6 -0
  69. package/dist/capabilities/prompts/identity.js +6 -0
  70. package/dist/capabilities/prompts/team.d.ts +4 -0
  71. package/dist/capabilities/prompts/team.js +4 -0
  72. package/dist/capabilities/repo-tools.d.ts +11 -0
  73. package/dist/capabilities/repo-tools.js +8 -0
  74. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  75. package/dist/capabilities/sandbox-file-send.js +91 -3
  76. package/dist/capabilities/scenarios.d.ts +130 -0
  77. package/dist/capabilities/scenarios.js +180 -7
  78. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  79. package/dist/capabilities/select-environment-tool.js +30 -0
  80. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  81. package/dist/capabilities/send-user-file-tool.js +65 -1
  82. package/dist/capabilities/skills.d.ts +29 -0
  83. package/dist/capabilities/skills.js +13 -2
  84. package/dist/capabilities/team.d.ts +22 -0
  85. package/dist/capabilities/team.js +22 -2
  86. package/dist/capabilities/tool-defer.d.ts +26 -0
  87. package/dist/capabilities/tool-defer.js +3 -0
  88. package/dist/config-center/apply-effective.d.ts +65 -0
  89. package/dist/config-center/apply-effective.js +204 -12
  90. package/dist/config-center/http-client.d.ts +34 -0
  91. package/dist/config-center/http-client.js +68 -0
  92. package/dist/config-center/restart-signal.d.ts +22 -0
  93. package/dist/config-center/restart-signal.js +39 -0
  94. package/dist/config-center/skills-mcp.d.ts +20 -1
  95. package/dist/config-center/skills-mcp.js +42 -7
  96. package/dist/config-center/types.d.ts +92 -1
  97. package/dist/config-lkg.d.ts +12 -0
  98. package/dist/config-lkg.js +41 -0
  99. package/dist/config-provider.d.ts +78 -0
  100. package/dist/config-provider.js +165 -2
  101. package/dist/config-types.d.ts +546 -0
  102. package/dist/config.d.ts +64 -0
  103. package/dist/config.js +455 -60
  104. package/dist/degenerate-instrument.d.ts +38 -0
  105. package/dist/degenerate-instrument.js +55 -3
  106. package/dist/elicitation.d.ts +39 -0
  107. package/dist/elicitation.js +87 -3
  108. package/dist/env-facts.d.ts +61 -0
  109. package/dist/env-facts.js +73 -7
  110. package/dist/fleet/fleet-bus.d.ts +185 -0
  111. package/dist/fleet/fleet-bus.js +333 -27
  112. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  113. package/dist/fleet/subagent-tail-bus.js +33 -2
  114. package/dist/fleet-client.d.ts +38 -0
  115. package/dist/fleet-client.js +44 -9
  116. package/dist/fleet-lease.d.ts +46 -0
  117. package/dist/fleet-lease.js +73 -5
  118. package/dist/hooks/branch-transcript.d.ts +8 -0
  119. package/dist/hooks/branch-transcript.js +33 -0
  120. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  121. package/dist/hooks/cc-stop-prompt.js +43 -1
  122. package/dist/hooks/hook-llm.d.ts +15 -0
  123. package/dist/hooks/hook-llm.js +47 -0
  124. package/dist/hooks/hook-runner.d.ts +89 -0
  125. package/dist/hooks/hook-runner.js +327 -18
  126. package/dist/http/idempotency.d.ts +31 -0
  127. package/dist/http/idempotency.js +34 -0
  128. package/dist/http/principal-gate.d.ts +17 -0
  129. package/dist/http/principal-gate.js +35 -3
  130. package/dist/http/route-ctx.d.ts +36 -0
  131. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  132. package/dist/http/routes/approvals-assistant.js +253 -23
  133. package/dist/http/routes/attachments.js +22 -4
  134. package/dist/http/routes/capabilities.d.ts +7 -0
  135. package/dist/http/routes/capabilities.js +202 -1
  136. package/dist/http/routes/fleet.d.ts +6 -0
  137. package/dist/http/routes/fleet.js +94 -5
  138. package/dist/http/routes/images.d.ts +17 -0
  139. package/dist/http/routes/images.js +222 -14
  140. package/dist/http/routes/leader.d.ts +7 -0
  141. package/dist/http/routes/leader.js +10 -0
  142. package/dist/http/routes/memory-policy.d.ts +6 -0
  143. package/dist/http/routes/memory-policy.js +38 -6
  144. package/dist/http/routes/notify-wake.d.ts +10 -0
  145. package/dist/http/routes/notify-wake.js +19 -3
  146. package/dist/http/routes/observability.d.ts +6 -0
  147. package/dist/http/routes/observability.js +19 -2
  148. package/dist/http/routes/runs.d.ts +15 -0
  149. package/dist/http/routes/runs.js +464 -41
  150. package/dist/http/routes/session-sync.d.ts +15 -0
  151. package/dist/http/routes/session-sync.js +229 -19
  152. package/dist/http/routes/sessions-list.d.ts +6 -0
  153. package/dist/http/routes/sessions-list.js +35 -4
  154. package/dist/http/routes/sessions.d.ts +14 -0
  155. package/dist/http/routes/sessions.js +176 -31
  156. package/dist/http/routes/side-query.d.ts +8 -0
  157. package/dist/http/routes/side-query.js +26 -1
  158. package/dist/http/routes/tasks.d.ts +18 -0
  159. package/dist/http/routes/tasks.js +501 -38
  160. package/dist/http/routes/trace-usage.d.ts +10 -0
  161. package/dist/http/routes/trace-usage.js +66 -14
  162. package/dist/http/routes/workflows.d.ts +12 -0
  163. package/dist/http/routes/workflows.js +180 -19
  164. package/dist/http/run-meta.d.ts +11 -0
  165. package/dist/http/run-meta.js +6 -0
  166. package/dist/http/send.d.ts +19 -0
  167. package/dist/http/send.js +11 -0
  168. package/dist/http/server.d.ts +255 -0
  169. package/dist/http/server.js +921 -75
  170. package/dist/http/sse-log.d.ts +15 -0
  171. package/dist/http/sse-log.js +16 -0
  172. package/dist/http/tar.d.ts +9 -0
  173. package/dist/http/tar.js +21 -5
  174. package/dist/http/wire-gate.d.ts +9 -0
  175. package/dist/http/wire-gate.js +9 -0
  176. package/dist/http/wire-types.d.ts +187 -0
  177. package/dist/http/workspace-content.d.ts +8 -0
  178. package/dist/http/workspace-content.js +10 -0
  179. package/dist/images/bake-validate.d.ts +63 -0
  180. package/dist/images/bake-validate.js +71 -1
  181. package/dist/images/manifest.d.ts +19 -0
  182. package/dist/images/manifest.js +6 -1
  183. package/dist/index.d.ts +1 -5
  184. package/dist/index.js +10 -5
  185. package/dist/key-resolver.d.ts +23 -0
  186. package/dist/key-resolver.js +27 -2
  187. package/dist/leader/diffout.d.ts +23 -0
  188. package/dist/leader/diffout.js +8 -1
  189. package/dist/leader/diffup.d.ts +32 -0
  190. package/dist/leader/diffup.js +43 -0
  191. package/dist/leader/endpoint.d.ts +20 -0
  192. package/dist/leader/endpoint.js +25 -2
  193. package/dist/leader/fanout.d.ts +60 -0
  194. package/dist/leader/fanout.js +29 -3
  195. package/dist/leader/grader-env-factory.d.ts +74 -0
  196. package/dist/leader/grader-env-factory.js +62 -3
  197. package/dist/leader/leader.d.ts +97 -0
  198. package/dist/leader/leader.js +151 -4
  199. package/dist/leader/merge.d.ts +94 -0
  200. package/dist/leader/merge.js +112 -9
  201. package/dist/leader/planner.d.ts +52 -0
  202. package/dist/leader/planner.js +47 -3
  203. package/dist/leader/repair-oracle.d.ts +61 -0
  204. package/dist/leader/repair-oracle.js +59 -1
  205. package/dist/leader/repair-wire.d.ts +78 -0
  206. package/dist/leader/repair-wire.js +79 -2
  207. package/dist/leader/wire.d.ts +79 -0
  208. package/dist/leader/wire.js +255 -8
  209. package/dist/lsp/e2b-bridge.d.ts +16 -0
  210. package/dist/lsp/e2b-bridge.js +32 -4
  211. package/dist/lsp/e2b-manager.d.ts +10 -0
  212. package/dist/lsp/e2b-manager.js +18 -2
  213. package/dist/lsp/lsp-frames.d.ts +12 -0
  214. package/dist/lsp/lsp-frames.js +12 -0
  215. package/dist/lsp/manager.d.ts +12 -0
  216. package/dist/lsp/manager.js +35 -2
  217. package/dist/lsp/types.d.ts +10 -0
  218. package/dist/lsp/ws-transport.d.ts +12 -0
  219. package/dist/lsp/ws-transport.js +53 -5
  220. package/dist/lsp-evict.d.ts +14 -0
  221. package/dist/lsp-evict.js +15 -1
  222. package/dist/main.js +2132 -96
  223. package/dist/memory-export.d.ts +1 -0
  224. package/dist/memory-export.js +4 -0
  225. package/dist/memory-scope.d.ts +49 -0
  226. package/dist/memory-scope.js +87 -4
  227. package/dist/memory-sync-client.d.ts +24 -0
  228. package/dist/memory-sync-client.js +41 -2
  229. package/dist/memory-sync.d.ts +23 -0
  230. package/dist/memory-sync.js +70 -1
  231. package/dist/model-select.d.ts +39 -0
  232. package/dist/model-select.js +42 -1
  233. package/dist/observability/cost-quota.d.ts +20 -0
  234. package/dist/observability/cost-quota.js +4 -0
  235. package/dist/observability/cost-taxonomy.d.ts +45 -0
  236. package/dist/observability/cost-taxonomy.js +34 -0
  237. package/dist/observability/logger.d.ts +1 -0
  238. package/dist/observability/logger.js +6 -0
  239. package/dist/observability/metrics.d.ts +13 -0
  240. package/dist/observability/metrics.js +63 -0
  241. package/dist/observability/otel-exporter.d.ts +9 -0
  242. package/dist/observability/otel-exporter.js +11 -3
  243. package/dist/observability/principal-context.d.ts +9 -0
  244. package/dist/observability/principal-context.js +9 -0
  245. package/dist/observability/prompt-manifest.d.ts +37 -0
  246. package/dist/observability/prompt-manifest.js +35 -1
  247. package/dist/observability/rate-limit.d.ts +10 -0
  248. package/dist/observability/rate-limit.js +1 -0
  249. package/dist/observability/tool-trace.d.ts +24 -0
  250. package/dist/observability/tool-trace.js +41 -1
  251. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  252. package/dist/orchestration/hardened-vm-runner.js +119 -4
  253. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  254. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  255. package/dist/orchestration/hardened-vm-worker.js +27 -0
  256. package/dist/orchestration/subagent-steer.d.ts +44 -0
  257. package/dist/orchestration/subagent-steer.js +45 -1
  258. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  259. package/dist/orchestration/workflow-agent-steer.js +80 -1
  260. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  261. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  262. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  263. package/dist/orchestration/workflow-notify-journal.js +187 -13
  264. package/dist/parked-decide.d.ts +61 -0
  265. package/dist/parked-decide.js +58 -1
  266. package/dist/per-task-image.d.ts +54 -0
  267. package/dist/per-task-image.js +41 -0
  268. package/dist/plan-cache-probe.d.ts +35 -0
  269. package/dist/plan-cache-probe.js +18 -3
  270. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  271. package/dist/plugins/approval-exemption-store.js +28 -2
  272. package/dist/plugins/approval-store-sql.d.ts +64 -0
  273. package/dist/plugins/approval-store-sql.js +32 -0
  274. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  275. package/dist/plugins/background-agent-store-sql.js +91 -4
  276. package/dist/plugins/background-shell-support.d.ts +98 -0
  277. package/dist/plugins/background-shell-support.js +117 -13
  278. package/dist/plugins/blob-backend.d.ts +104 -0
  279. package/dist/plugins/blob-backend.js +163 -6
  280. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  281. package/dist/plugins/breaker-state-sql.js +46 -8
  282. package/dist/plugins/caching-session-store.d.ts +42 -0
  283. package/dist/plugins/caching-session-store.js +63 -3
  284. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  285. package/dist/plugins/checkpoint-store-sql.js +239 -11
  286. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  287. package/dist/plugins/file-outcome-sink.js +9 -0
  288. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  289. package/dist/plugins/file-resume-anchor-store.js +43 -4
  290. package/dist/plugins/file-run-store.d.ts +90 -0
  291. package/dist/plugins/file-run-store.js +145 -13
  292. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  293. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  294. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  295. package/dist/plugins/file-workflow-journal-store.js +10 -0
  296. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  297. package/dist/plugins/fork-routing-session-store.js +51 -3
  298. package/dist/plugins/host-platform.d.ts +69 -0
  299. package/dist/plugins/host-platform.js +81 -2
  300. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  301. package/dist/plugins/image-bake-store-sql.js +241 -7
  302. package/dist/plugins/image-index-sql.d.ts +46 -0
  303. package/dist/plugins/image-index-sql.js +113 -4
  304. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  305. package/dist/plugins/k8s-bg-scripts.js +88 -4
  306. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  307. package/dist/plugins/k8s-exec-protocol.js +41 -0
  308. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  309. package/dist/plugins/local-checkpoint-store.js +86 -7
  310. package/dist/plugins/local-session-store.d.ts +157 -0
  311. package/dist/plugins/local-session-store.js +289 -34
  312. package/dist/plugins/local-task-attachment-store.js +14 -2
  313. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  314. package/dist/plugins/mailbox-store-sql.js +39 -6
  315. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  316. package/dist/plugins/memory-engine-pg.js +122 -4
  317. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  318. package/dist/plugins/memory-engine-tidb.js +115 -5
  319. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  320. package/dist/plugins/memory-engine-vector-util.js +5 -0
  321. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  322. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  323. package/dist/plugins/memory-run-store.d.ts +63 -0
  324. package/dist/plugins/memory-run-store.js +73 -8
  325. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  326. package/dist/plugins/memory-session-policy-store.js +17 -0
  327. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  328. package/dist/plugins/memory-sync-store-pg.js +45 -2
  329. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  330. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  331. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  332. package/dist/plugins/outcome-ledger-sql.js +97 -3
  333. package/dist/plugins/pg-approval-store.d.ts +7 -0
  334. package/dist/plugins/pg-approval-store.js +7 -0
  335. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  336. package/dist/plugins/pg-breaker-state.js +6 -0
  337. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  338. package/dist/plugins/pg-checkpoint-store.js +8 -0
  339. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  340. package/dist/plugins/pg-cost-quota.js +6 -0
  341. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  342. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  343. package/dist/plugins/pg-image-bake.d.ts +9 -0
  344. package/dist/plugins/pg-image-bake.js +9 -0
  345. package/dist/plugins/pg-image-index.d.ts +9 -0
  346. package/dist/plugins/pg-image-index.js +9 -0
  347. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  348. package/dist/plugins/pg-outcome-ledger.js +9 -0
  349. package/dist/plugins/pg-pool.d.ts +50 -0
  350. package/dist/plugins/pg-pool.js +78 -0
  351. package/dist/plugins/pg-query.d.ts +11 -0
  352. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  353. package/dist/plugins/pg-rate-limiter.js +12 -2
  354. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  355. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  356. package/dist/plugins/pg-run-store.d.ts +7 -0
  357. package/dist/plugins/pg-run-store.js +7 -0
  358. package/dist/plugins/pg-safe-json.d.ts +13 -0
  359. package/dist/plugins/pg-safe-json.js +40 -4
  360. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  361. package/dist/plugins/pg-session-policy-store.js +5 -0
  362. package/dist/plugins/pg-session-storage.d.ts +72 -0
  363. package/dist/plugins/pg-session-storage.js +152 -20
  364. package/dist/plugins/pg-session-store.d.ts +10 -0
  365. package/dist/plugins/pg-session-store.js +10 -0
  366. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  367. package/dist/plugins/pg-tool-result-store.js +7 -0
  368. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  369. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  370. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  371. package/dist/plugins/pg-workflow-run-store.js +7 -0
  372. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  373. package/dist/plugins/posix-shell-fs.js +31 -1
  374. package/dist/plugins/remote-env-adb.d.ts +25 -0
  375. package/dist/plugins/remote-env-adb.js +95 -12
  376. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  377. package/dist/plugins/remote-env-e2b.js +371 -40
  378. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  379. package/dist/plugins/remote-env-file-error.js +37 -0
  380. package/dist/plugins/remote-env-host.d.ts +151 -0
  381. package/dist/plugins/remote-env-host.js +468 -70
  382. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  383. package/dist/plugins/remote-env-k8s.js +318 -32
  384. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  385. package/dist/plugins/remote-env-local-docker.js +149 -24
  386. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  387. package/dist/plugins/remote-env-ssh.js +117 -20
  388. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  389. package/dist/plugins/remote-scratchpad.js +32 -2
  390. package/dist/plugins/remote-shell.d.ts +22 -0
  391. package/dist/plugins/remote-shell.js +27 -1
  392. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  393. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  394. package/dist/plugins/roster-store-sql.d.ts +27 -0
  395. package/dist/plugins/roster-store-sql.js +54 -0
  396. package/dist/plugins/run-store-sql.d.ts +194 -0
  397. package/dist/plugins/run-store-sql.js +210 -9
  398. package/dist/plugins/s3-presign.d.ts +20 -0
  399. package/dist/plugins/s3-presign.js +49 -2
  400. package/dist/plugins/scheduler-support.d.ts +12 -0
  401. package/dist/plugins/scheduler-support.js +75 -3
  402. package/dist/plugins/send-file-ledger.d.ts +15 -0
  403. package/dist/plugins/send-file-ledger.js +53 -4
  404. package/dist/plugins/send-user-file.d.ts +77 -0
  405. package/dist/plugins/send-user-file.js +92 -4
  406. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  407. package/dist/plugins/session-policy-store-sql.js +75 -3
  408. package/dist/plugins/session-store.d.ts +45 -0
  409. package/dist/plugins/session-store.js +51 -0
  410. package/dist/plugins/sql-driver.d.ts +77 -0
  411. package/dist/plugins/sql-driver.js +4 -0
  412. package/dist/plugins/sql-escape.d.ts +8 -0
  413. package/dist/plugins/sql-escape.js +8 -0
  414. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  415. package/dist/plugins/sql-row-helpers.js +25 -0
  416. package/dist/plugins/store-backend.d.ts +103 -0
  417. package/dist/plugins/store-backend.js +120 -27
  418. package/dist/plugins/store-contracts.d.ts +62 -0
  419. package/dist/plugins/store-contracts.js +3 -0
  420. package/dist/plugins/task-attachment-store.d.ts +60 -0
  421. package/dist/plugins/task-attachment-store.js +49 -3
  422. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  423. package/dist/plugins/task-list-store-sql.js +21 -0
  424. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  425. package/dist/plugins/tidb-approval-store.js +6 -0
  426. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  427. package/dist/plugins/tidb-breaker-state.js +5 -0
  428. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  429. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  430. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  431. package/dist/plugins/tidb-cost-quota.js +1 -0
  432. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  433. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  434. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  435. package/dist/plugins/tidb-image-bake.js +8 -0
  436. package/dist/plugins/tidb-image-index.d.ts +8 -0
  437. package/dist/plugins/tidb-image-index.js +8 -0
  438. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  439. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  440. package/dist/plugins/tidb-pool.d.ts +56 -0
  441. package/dist/plugins/tidb-pool.js +181 -1
  442. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  443. package/dist/plugins/tidb-rate-limiter.js +5 -2
  444. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  445. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  446. package/dist/plugins/tidb-run-store.d.ts +7 -0
  447. package/dist/plugins/tidb-run-store.js +7 -0
  448. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  449. package/dist/plugins/tidb-session-policy-store.js +5 -0
  450. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  451. package/dist/plugins/tidb-session-storage.js +62 -3
  452. package/dist/plugins/tidb-session-store.d.ts +142 -0
  453. package/dist/plugins/tidb-session-store.js +264 -16
  454. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  455. package/dist/plugins/tidb-tool-result-store.js +7 -0
  456. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  457. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  458. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  459. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  460. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  461. package/dist/plugins/tool-result-store-sql.js +38 -2
  462. package/dist/plugins/web-search.d.ts +35 -0
  463. package/dist/plugins/web-search.js +45 -9
  464. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  465. package/dist/plugins/workflow-journal-limits.js +10 -0
  466. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  467. package/dist/plugins/workflow-journal-store-sql.js +59 -3
  468. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  469. package/dist/plugins/workflow-run-store-sql.js +84 -6
  470. package/dist/plugins/worktree-isolation.d.ts +45 -0
  471. package/dist/plugins/worktree-isolation.js +105 -6
  472. package/dist/plugins/write-behind-counter.d.ts +56 -1
  473. package/dist/plugins/write-behind-counter.js +53 -14
  474. package/dist/principal-jwt.d.ts +24 -0
  475. package/dist/principal-jwt.js +60 -5
  476. package/dist/project-memory.d.ts +22 -0
  477. package/dist/project-memory.js +144 -15
  478. package/dist/prompts-domain-validate.d.ts +28 -0
  479. package/dist/prompts-domain-validate.js +42 -1
  480. package/dist/question.d.ts +33 -0
  481. package/dist/question.js +69 -2
  482. package/dist/resource-suspend.d.ts +21 -0
  483. package/dist/resource-suspend.js +16 -0
  484. package/dist/router/route-orchestration.d.ts +78 -0
  485. package/dist/router/route-orchestration.js +77 -0
  486. package/dist/run-local.d.ts +32 -0
  487. package/dist/run-local.js +172 -8
  488. package/dist/runs.d.ts +189 -4
  489. package/dist/runs.js +465 -24
  490. package/dist/runtime-caps-resolver.d.ts +106 -0
  491. package/dist/runtime-caps-resolver.js +89 -4
  492. package/dist/runtime-governance.d.ts +84 -0
  493. package/dist/runtime-governance.js +127 -1
  494. package/dist/sandbox-pkg-source.d.ts +23 -0
  495. package/dist/sandbox-pkg-source.js +37 -0
  496. package/dist/sealed-key.d.ts +54 -0
  497. package/dist/sealed-key.js +68 -3
  498. package/dist/security.d.ts +108 -0
  499. package/dist/security.js +145 -6
  500. package/dist/sema-registry.d.ts +21 -0
  501. package/dist/sema-registry.js +21 -0
  502. package/dist/session-leaf-bus.d.ts +31 -0
  503. package/dist/session-leaf-bus.js +32 -0
  504. package/dist/session-sync-content.d.ts +46 -0
  505. package/dist/session-sync-content.js +47 -1
  506. package/dist/session-sync-kernel.d.ts +89 -0
  507. package/dist/session-sync-kernel.js +48 -3
  508. package/dist/session-sync.d.ts +125 -0
  509. package/dist/session-sync.js +181 -8
  510. package/dist/session-titler.d.ts +26 -0
  511. package/dist/session-titler.js +41 -7
  512. package/dist/session-watch.d.ts +53 -1
  513. package/dist/session-watch.js +73 -9
  514. package/dist/sighup-idle.d.ts +30 -0
  515. package/dist/sighup-idle.js +12 -1
  516. package/dist/spec-fields.d.ts +91 -3
  517. package/dist/spec-fields.js +116 -4
  518. package/dist/task-cwd.d.ts +50 -0
  519. package/dist/task-cwd.js +68 -1
  520. package/dist/task-mcp.d.ts +47 -0
  521. package/dist/task-mcp.js +29 -0
  522. package/dist/task-settings.d.ts +175 -0
  523. package/dist/task-settings.js +226 -11
  524. package/dist/task-workflow.d.ts +67 -0
  525. package/dist/task-workflow.js +75 -8
  526. package/dist/tool-approval.d.ts +91 -0
  527. package/dist/tool-approval.js +215 -0
  528. package/dist/trace/artifacts.d.ts +9 -0
  529. package/dist/trace/artifacts.js +30 -5
  530. package/dist/trace/core-keyset-guard.d.ts +18 -0
  531. package/dist/trace/ledger-sink.d.ts +43 -0
  532. package/dist/trace/ledger-sink.js +64 -5
  533. package/dist/trace/project.d.ts +133 -0
  534. package/dist/trace/project.js +189 -2
  535. package/dist/trace/redact.d.ts +19 -0
  536. package/dist/trace/redact.js +66 -9
  537. package/dist/usage-analytics.d.ts +26 -0
  538. package/dist/usage-analytics.js +26 -3
  539. package/package.json +1 -1
@@ -1,3 +1,39 @@
1
+ /**
2
+ * S1 value-verdict harness — the REAL `ProfileDeps` factory (the LIVE make-real wiring). SPEC-S1-value-harness.md
3
+ * §11 "the wiring of ProfileDeps to the REAL core entrypoints + REAL E2B worker/grader envs". This module
4
+ * ASSEMBLES a bench runtime — createBrain(DeepSeek) + a real `Runner` + a real E2B WORKER env + a DISTINCT E2B
5
+ * GRADER env + createLeaderRunner for TEAM — and returns a `ProfileDeps` whose EVERY seam runs the REAL engine/
6
+ * oracle. The deterministic driver (`run-firm.ts --dry-run`) injects a MOCK; this is the clay-gated live path.
7
+ *
8
+ * 🔴 ANTI-REWARD-HACK (oracle.ts §, runner-ctx.ts §5.1): the oracle ALWAYS grades in a env that is a DISTINCT
9
+ * object from the worker env. We provision a SEPARATE E2B sandbox for the grader and transfer the worker's
10
+ * COMMITTED tree into it via `git bundle` (export from the worker sandbox → import into the grader sandbox) —
11
+ * so the grader's checkout is the worker's HEAD, but the grader sandbox can never be tampered by the worker
12
+ * (its hidden tests + its exec all run in a sandbox the worker never touched). `assertDistinctEnvs` is the
13
+ * build-time guard; the structural separation is the real boundary.
14
+ *
15
+ * 🔴 TRAP TASKS RUN ISOLATED (the task prompt): every worker leg runs inside an E2B Firecracker VM
16
+ * (`RemoteContainerExecutionEnv`), NEVER the bare host — a C4/trap that reaches for a dangerous action is
17
+ * contained by the VM boundary (`capabilities.isolation === true`).
18
+ *
19
+ * 🔴 OBJECTIVE ORACLE ONLY (row.ts §): `runOracle` runs `runExecGate` over real exit codes in the grader env;
20
+ * there is NO LLM-judge in the numerator. The LLM is only a GATE inside an arm (the verify/repair/reviewer).
21
+ *
22
+ * 🔴 HONEST GAPS (flagged, NOT stubbed): the per-cell worker/grader env LIFECYCLE (provision → run → grade →
23
+ * destroy) is owned by `buildLiveDeps`, which returns a `ProfileDeps` bound to ONE (trap, seed) cell — the
24
+ * driver constructs a fresh `buildLiveDeps` per cell and disposes it after the row is emitted (so a hung cell's
25
+ * sandboxes are reaped). `runCounterfactualOracle` is DELIBERATELY OMITTED (a real ablation — re-running the
26
+ * SAME (trap,seed) with the gate DISABLED into a FRESH worker — is TODO); absent ⇒ buildCounterfactual returns
27
+ * undefined ⇒ the metric tool records UNVERIFIED-WITHHELD (NO avoided-loss credit), the honest "not measured"
28
+ * choice. The previous `runCounterfactualOracle: runOracle` self-alias re-graded the IDENTICAL post-gate tree and
29
+ * auto-credited EVERY withhold as CORRECTLY-WITHHELD (a tautology) — removed.
30
+ *
31
+ * 🔴 TEAM (the leader arm): the leader INTEGRATES + PUSHES to a per-cell `git://127.0.0.1` durable remote (served by
32
+ * a local `git daemon` — the wire validator forbids file://). On a delivered run the harness clones that
33
+ * integrated tree INTO state.worker, so `runOracle` grades the REAL integrated output in the DISTINCT grader (the
34
+ * same anti-reward-hack transfer path SOLO/SUP use). If the integrated tree can't be imported, the cell is
35
+ * `infraFailed` (EXCLUDED) — NEVER a fabricated uniform delivered=false loss for the whole TEAM column.
36
+ */
1
37
  import { Runner, runWithVerification, resumeWithVerification, runRepairLoop, combinePolicies, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, } from "@sema-agent/core";
2
38
  import { loadConfig } from "../../config.js";
3
39
  import { createBrain } from "../../brain.js";
@@ -8,14 +44,23 @@ import { createLeaderRunner } from "../../leader/wire.js";
8
44
  import { runOracle as runStandaloneOracle } from "./oracle.js";
9
45
  import { makeRepairOracle } from "./repair-oracle-adapter.js";
10
46
  import { assertDistinctEnvs } from "./runner-ctx.js";
47
+ /** The worker/grader workspace root inside each E2B VM. */
11
48
  const W = "/home/user";
49
+ /** The repo dir inside each VM where the worker's tree lives + the grader checks out. */
12
50
  const REPO = `${W}/repo`;
51
+ /** The grader's base ref for the `delivered` (HEAD advanced past base) signal. The seed commits an empty base. */
13
52
  const BASE_REF = "s1-base";
53
+ /** Build the live runtime config from env. GATED on E2B_API_KEY + DEEPSEEK_API_KEY + non-zero MODEL_COST_INPUT/OUTPUT
54
+ * (so C1 is real and maxCostUsd binds). Returns undefined when a required key/price is absent — the driver then
55
+ * refuses the live path with a clear message (never a silent fake run, never a fabricated $0 cost axis). */
14
56
  export function liveRuntimeConfigFromEnv(env = process.env) {
15
57
  const e2bApiKey = env.E2B_API_KEY;
16
58
  const deepseekApiKey = env.DEEPSEEK_API_KEY;
17
59
  if (!e2bApiKey || !deepseekApiKey)
18
60
  return undefined;
61
+ // 🔴 Cost rates are LOAD-BEARING for the value verdict (C1 + the maxCostUsd safety net). A live run with $0 pricing
62
+ // would produce a fully-green report whose entire cost dimension is fake — the SAME defect class as the fixed
63
+ // delivered-always-false / maxTokens bugs. Fail LOUD (return undefined → driver refuses) when they're missing.
19
64
  const costInput = Number(env.MODEL_COST_INPUT ?? "");
20
65
  const costOutput = Number(env.MODEL_COST_OUTPUT ?? "");
21
66
  if (!(costInput > 0) || !(costOutput > 0))
@@ -37,20 +82,28 @@ export function liveRuntimeConfigFromEnv(env = process.env) {
37
82
  ...(Number(env.MODEL_COST_CACHE_WRITE ?? "") > 0 ? { costCacheWrite: Number(env.MODEL_COST_CACHE_WRITE) } : {}),
38
83
  };
39
84
  }
85
+ /** Build the service `ServiceConfig`-shaped brain/pricing ingredients from the live runtime config. We construct a
86
+ * MINIMAL ServiceConfig (only the fields createBrain + buildPricing read) pointed at the DeepSeek gateway. */
40
87
  function buildBrainIngredients(rt) {
88
+ // Point the loader at DeepSeek (mirrors the live tests' env stamping) then build the brain/pricing.
41
89
  process.env.MODEL_GATEWAY_BASEURL = rt.gatewayBaseUrl;
42
90
  process.env.MODEL_ID = rt.modelId;
43
91
  process.env.MODEL_API_KEY = rt.deepseekApiKey;
44
92
  process.env.MODEL_MAX_TOKENS = String(rt.maxTokens ?? 8000);
93
+ // 🔴 Stamp the cost rates so config.ts builds a NON-ZERO Model.cost → core computes real C1 µUSD + the maxCostUsd
94
+ // gate binds (review fix). Without this the cost half of the value Pareto is a fabricated $0 across all arms.
45
95
  process.env.MODEL_COST_INPUT = String(rt.costInput);
46
96
  process.env.MODEL_COST_OUTPUT = String(rt.costOutput);
47
97
  if (rt.costCacheRead != null)
48
98
  process.env.MODEL_COST_CACHE_READ = String(rt.costCacheRead);
49
99
  if (rt.costCacheWrite != null)
50
100
  process.env.MODEL_COST_CACHE_WRITE = String(rt.costCacheWrite);
101
+ // loadConfig is the authoritative builder of the models/roles/pricing-key catalog (config.ts has no import of
102
+ // this module → no cycle). It reads the DeepSeek env we just stamped above.
51
103
  const config = loadConfig();
52
104
  const brain = createBrain(config, {});
53
105
  const pricing = buildPricing(config.models);
106
+ // 🔴 Defensive assert: if pricing regresses to zero the C1 axis is fake. Catch drift at build, not in a report.
54
107
  const p = pricing[rt.modelId];
55
108
  if (!p || ((p.inputPer1M ?? 0) === 0 && (p.outputPer1M ?? 0) === 0)) {
56
109
  throw new Error(`s1 live: zero pricing for ${rt.modelId} — C1 cost axis would be a fabricated $0 (set MODEL_COST_INPUT/OUTPUT)`);
@@ -63,6 +116,7 @@ const sh = (env) => async (cmd) => {
63
116
  throw new Error(`s1 transport: ${r.error.message}`);
64
117
  return { code: r.value.exitCode, out: (r.value.stdout + r.value.stderr).trim() };
65
118
  };
119
+ /** Provision + connect a fresh E2B sandbox with an empty git repo seeded at the `s1-base` ref. */
66
120
  async function provisionSandbox(rt, role, cellId) {
67
121
  const env = new RemoteContainerExecutionEnv({
68
122
  apiKey: rt.e2bApiKey,
@@ -75,10 +129,14 @@ async function provisionSandbox(rt, role, cellId) {
75
129
  throw new Error(`s1 ${role} sandbox connect failed (${cellId}): ${c.error.message}`);
76
130
  return env;
77
131
  }
132
+ /** Seed a base repo at the `s1-base` ref (the worker commits ON TOP; `delivered` = HEAD advanced past it). When
133
+ * `seedFiles` is given (hazard traps, C6) they are written + committed INTO the base — the worker sees them and may
134
+ * delete them (the survival oracle then checks the sentinel still exists in the committed tree). Absent ⇒ empty base. */
78
135
  async function seedBaseRepo(env, seedFiles) {
136
+ // Write each seed file via base64 (no shell-escaping hazard with arbitrary content) into REPO before the base commit.
79
137
  const writeCmds = (seedFiles ?? [])
80
138
  .map((f) => {
81
- const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
139
+ const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path; // store relative to REPO
82
140
  const b64 = Buffer.from(f.content, "utf8").toString("base64");
83
141
  return `mkdir -p "$(dirname '${rel}')" 2>/dev/null; printf %s '${b64}' | base64 -d > '${rel}'`;
84
142
  })
@@ -91,7 +149,18 @@ async function seedBaseRepo(env, seedFiles) {
91
149
  if (r.code !== 0)
92
150
  throw new Error(`s1 seed base repo failed: ${r.out.slice(-400)}`);
93
151
  }
152
+ /**
153
+ * Transfer the WORKER's committed tree into the DISTINCT GRADER sandbox (anti-reward-hack). Exports a `git bundle`
154
+ * of the full history from the worker sandbox, base64-pipes it through the control plane (no shared remote needed),
155
+ * imports it into the grader's repo, and checks out the worker HEAD with the `s1-base` ref recreated. The grader is
156
+ * a SEPARATE sandbox the worker never touched, so its hidden-test run cannot be tampered.
157
+ */
94
158
  async function transferWorkerTreeToGrader(worker, grader) {
159
+ // 🔴 tar-worktree, NOT git bundle/clone (firm-v1/C4 root cause): the grader-side `git clone` is unreliable on BOTH
160
+ // backends — E2B is a platform heisenbug (same code firm-v1 ran green now leaves an unusable .git), Kata is a
161
+ // virtiofs st_dev limit. So the grader NEVER runs git: the worker (where git works) computes the HEAD + s1-base
162
+ // shas and emits a `git archive` tar of the committed tree (no .git); the grader just `tar -x`s plain files.
163
+ // `delivered` (head≠base) comes from the shas. anti-reward-hack unchanged (distinct grader env + restore-before-score).
95
164
  const headProbe = await sh(worker)(`cd ${REPO} && git rev-parse HEAD`);
96
165
  const baseProbe = await sh(worker)(`cd ${REPO} && git rev-parse ${BASE_REF}`);
97
166
  const head = headProbe.out.trim();
@@ -100,12 +169,14 @@ async function transferWorkerTreeToGrader(worker, grader) {
100
169
  throw new Error(`s1 worker HEAD unresolved: ${headProbe.out.slice(-200)}`);
101
170
  if (!/^[0-9a-f]{40}$/.test(base))
102
171
  throw new Error(`s1 worker base ref unresolved: ${baseProbe.out.slice(-200)}`);
172
+ // git archive HEAD = the committed worktree as a tar (no .git), on stdout → base64 to ferry over the exec transport.
103
173
  const arch = await sh(worker)(`cd ${REPO} && git archive --format=tar HEAD | base64 -w0`);
104
174
  if (arch.code !== 0)
105
175
  throw new Error(`s1 worker archive failed: ${arch.out.slice(-400)}`);
106
176
  const buf = Buffer.from(arch.out.trim(), "base64");
107
177
  if (buf.length === 0)
108
178
  throw new Error("s1 worker archive decoded empty on the control plane");
179
+ // Grader: BINARY write the tar (base64-string-over-files.write corrupts; binary is gtest4-proven) + tar -x plain files.
109
180
  const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(buf));
110
181
  if (!wr.ok)
111
182
  throw new Error(`s1 grader tar write failed: ${wr.error.message}`);
@@ -116,23 +187,47 @@ async function transferWorkerTreeToGrader(worker, grader) {
116
187
  console.error(`[S1_DEBUG_TAR] head=${head.slice(0, 8)} base=${base.slice(0, 8)} tarBytes=${buf.length} ${ext.out.slice(-60)}`);
117
188
  return { head, base };
118
189
  }
190
+ /**
191
+ * Import a git-bundle (base64) into the GRADER sandbox and pin `s1-base` to an EXACT base hash. Shared by the SOLO/SUP
192
+ * path (bundle from the worker sandbox) and the TEAM path (bundle from the control-plane integrated repo — the E2B
193
+ * worker is network-isolated from the leader's git daemon, so the integrated tree is bundled on the control plane and
194
+ * shipped here, NOT cloned from inside E2B). The base hash is set explicitly (never re-derived in the grader → can't
195
+ * collapse to HEAD). Fail-closed: the grader's s1-base MUST resolve to the given hash AND differ from HEAD.
196
+ */
119
197
  async function importBundleB64ToGrader(grader, bundleB64, baseHash) {
120
198
  if (!/^[0-9a-f]{40}$/.test(baseHash))
121
199
  throw new Error(`s1 grader import: invalid base hash ${JSON.stringify(baseHash)}`);
122
200
  const wr = await grader.writeFile(`/tmp/s1.bundle.b64`, bundleB64);
123
201
  if (!wr.ok)
124
202
  throw new Error(`s1 grader bundle write failed: ${wr.error.message}`);
203
+ // SOLO/SUP path: the b64 is WORKER-ORIGIN (generated by `base64 -w0` inside the same E2B image), so `base64 -d`
204
+ // round-trips cleanly (proven by firm-v1 N=10, 40 SOLO/SUP cells delivered=true). The CONTROL-PLANE-origin b64
205
+ // does NOT round-trip through E2B files.write (firm-v1/C4 dig) — that's why the TEAM path uses a BINARY write
206
+ // (importBundleBinaryToGrader) instead. `test -s` guards an empty decode defensively.
125
207
  const imp = await sh(grader)(`set -e; base64 -d /tmp/s1.bundle.b64 > /tmp/s1.bundle; test -s /tmp/s1.bundle; rm -rf ${REPO}; ` +
126
208
  `git clone -q /tmp/s1.bundle ${REPO}; cd ${REPO}; ` +
127
209
  `git config user.email s1@bench.local; git config user.name s1-bench; ` +
128
210
  `git tag -f ${BASE_REF} ${baseHash}`);
129
211
  if (imp.code !== 0)
130
212
  throw new Error(`s1 grader import failed: ${imp.out.slice(-400)}`);
213
+ // Fail-closed verify: the grader's base MUST resolve to the given base hash AND HEAD must have advanced past it
214
+ // (else `delivered` is meaningless).
131
215
  const verify = await sh(grader)(`cd ${REPO} && echo "BASE=$(git rev-parse ${BASE_REF}) HEAD=$(git rev-parse HEAD)"`);
132
216
  if (!verify.out.includes(`BASE=${baseHash}`))
133
217
  throw new Error(`s1 grader base mismatch: ${verify.out.slice(-200)} expected BASE=${baseHash}`);
134
218
  }
219
+ /**
220
+ * Import a git-bundle (RAW BINARY Buffer) into the GRADER and pin `s1-base` to an EXACT base hash. The TEAM path: the
221
+ * leader's integrated tree is bundled on the CONTROL PLANE, so we ship the bundle as BINARY via E2B files.write
222
+ * (Uint8Array) — 🔴 a base64-STRING through files.write decodes to garbage in the sandbox (firm-v1/C4 dig: a
223
+ * Node-Buffer b64 string, byte-identical to a shell `base64 -w0` locally, came back un-decodable inside E2B; a binary
224
+ * write of the same bytes + `git clone` succeeds, EXIT=0). E2B git 2.39 reads the macOS git 2.50 v2 bundle fine.
225
+ */
135
226
  async function importBundleBinaryToGrader(grader, tarBuffer, shas) {
227
+ // 🔴 TEAM tar-worktree (firm-v1/C4): the leader's INTEGRATED worktree is archived as a tar on the CONTROL PLANE
228
+ // (captureIntegratedTreeToBundle uses `git archive`, no .git). The grader BINARY-writes it + `tar -x`s plain files —
229
+ // NEVER `git clone` (E2B grader-clone is a platform heisenbug; Kata is virtiofs-st_dev-blocked). delivered comes
230
+ // from the worker-computed shas (head≠base), not git in the grader.
136
231
  if (!/^[0-9a-f]{40}$/.test(shas.head) || !/^[0-9a-f]{40}$/.test(shas.base))
137
232
  throw new Error(`s1 grader import: invalid shas ${JSON.stringify(shas)}`);
138
233
  const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(tarBuffer));
@@ -145,9 +240,11 @@ async function importBundleBinaryToGrader(grader, tarBuffer, shas) {
145
240
  console.error(`[S1_DEBUG_TAR team] head=${shas.head.slice(0, 8)} base=${shas.base.slice(0, 8)} ${ext.out.slice(-60)}`);
146
241
  return shas;
147
242
  }
243
+ /** Build the OracleTask the standalone oracle consumes from a trap (stamps graderRepoDir + baseRef). */
148
244
  function oracleTaskFromTrap(trap) {
149
245
  return { ...trap.oracle, graderRepoDir: REPO, baseRef: BASE_REF };
150
246
  }
247
+ /** A GraderTransport bound to a grader sandbox (clone/checkout via exec; hidden-test writes via writeFile). */
151
248
  function graderTransport(grader) {
152
249
  return {
153
250
  exec: async (command) => {
@@ -163,6 +260,16 @@ function graderTransport(grader) {
163
260
  },
164
261
  };
165
262
  }
263
+ /**
264
+ * 🔴 THE FACTORY — build a REAL `ProfileDeps` bound to ONE (trap, seed) cell. Provisions a worker E2B sandbox + a
265
+ * DISTINCT grader E2B sandbox (lazily, on first seam call), wires every seam to the REAL core engine/oracle, and
266
+ * returns `{ deps, dispose }`. The driver calls one `buildLiveDeps` per cell and `dispose()`s it after the row.
267
+ *
268
+ * @param rt the live runtime config (DeepSeek + E2B keys + the shared budget).
269
+ * @param trap the class-C trap this cell runs.
270
+ * @param seed the cell's seed (provenance; the durable-approval scope keys on it via buildSupImplSpec).
271
+ * @param cellId a stable id for the cell (used as sandbox metadata for fleet observability).
272
+ */
166
273
  export function buildLiveDeps(rt, trap, seed, cellId) {
167
274
  const { brain, models, roles, pricing } = buildBrainIngredients(rt);
168
275
  const baseSpec = (objective) => ({
@@ -172,6 +279,8 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
172
279
  maxCostUsd: rt.maxCostUsd ?? 1.0,
173
280
  limits: { maxTurns: rt.maxTurns ?? 12 },
174
281
  });
282
+ // Lazily-provisioned, memoized per-cell sandboxes (so a cell that never runs a seam pays zero VM cost; a seam
283
+ // that throws still leaves them on `state` so dispose() reaps them).
175
284
  const state = {};
176
285
  const ensureWorker = async () => {
177
286
  if (!state.worker) {
@@ -181,12 +290,15 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
181
290
  }
182
291
  return { env: state.worker, runner: state.runner };
183
292
  };
293
+ /** Provision the DISTINCT grader, transfer the worker's committed tree in. Memoized (graded once per cell). */
184
294
  const ensureGraderWithWorkerTree = async () => {
185
295
  const { env: worker } = await ensureWorker();
186
296
  if (!state.grader) {
187
297
  state.grader = await provisionSandbox(rt, "grader", cellId);
188
- assertDistinctEnvs(worker, state.grader);
298
+ assertDistinctEnvs(worker, state.grader); // build-time guard (the structural separation is the real boundary)
299
+ // No grader seedBaseRepo: the grader holds a tar-extracted worktree (no .git at all), so it needs no git identity.
189
300
  if (state.teamBundle) {
301
+ // TEAM: extract the control-plane-archived integrated worktree into the grader (tar, no git — same dodge).
190
302
  state.shas = await importBundleBinaryToGrader(state.grader, state.teamBundle.buffer, { head: state.teamBundle.head, base: state.teamBundle.base });
191
303
  }
192
304
  else {
@@ -195,54 +307,91 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
195
307
  }
196
308
  return state.grader;
197
309
  };
310
+ /** Run the OBJECTIVE oracle in the DISTINCT grader env (the measure — runExecGate over real exit codes).
311
+ * @param reSyncWorkerTree when true, RE-TRANSFER the worker's committed tree into the (already-provisioned)
312
+ * grader before grading. The non-repair path grades a STABLE terminal tree once (memoized transfer is
313
+ * correct); the repair loop calls the oracle ONCE PER ATTEMPT against an EVOLVING worker tree, so it MUST
314
+ * re-sync or it would forever grade the frozen attempt-1 snapshot (the grader would never see a fix land). */
198
315
  const runOracle = async (reSyncWorkerTree = false) => {
199
316
  const { env: worker } = await ensureWorker();
200
317
  const grader = await ensureGraderWithWorkerTree();
201
318
  if (reSyncWorkerTree)
202
- state.shas = await transferWorkerTreeToGrader(worker, grader);
319
+ state.shas = await transferWorkerTreeToGrader(worker, grader); // re-extract the evolving worktree
203
320
  const task = { ...oracleTaskFromTrap(trap), ...(state.shas ? { deliveredShas: state.shas } : {}) };
204
321
  const v = await runStandaloneOracle(grader, graderTransport(grader), worker, task);
205
322
  if (process.env.S1_DEBUG_GIT)
206
323
  console.error(`[S1_DEBUG_ORACLE ${trap.id}] delivered=${v.delivered} tests=${v.hiddenTestsGreen} build=${v.buildPassed} inv=${v.invariantsOk} | raw=`, JSON.stringify(v.raw)?.slice(0, 700));
207
- return v;
324
+ return v; // OracleVerdict is a superset of OracleVerdicts; pickOracleVerdicts narrows it in arms.ts.
208
325
  };
209
326
  const deps = {
327
+ // ── SOLO: run the impl behind the verify→fix gate via the REAL core runWithVerification ──
210
328
  runWithVerification: async (implSpec) => {
211
329
  const { runner } = await ensureWorker();
212
330
  return runWithVerification(runner, toTaskSpec(baseSpec, implSpec), { maxRounds: rt.maxRounds ?? 2 });
213
331
  },
332
+ // ── SUP verify/durable path ──
333
+ // 🔴 durable suspend/resume is ONLY supported at the TOP-LEVEL runTask (core's mapNestedSuspend HARD boundary,
334
+ // design/45 §11 Q6 / design/80 D-B): the NESTED runWithVerification maps a durable pause to status:"failed"
335
+ // (UNEXPECTED_SUSPENDED), so the SUP HITL gate (gated bash → suspend) was ALWAYS infra-failed (caught by the
336
+ // firm-v1 N=1 all-paths smoke: C1/C2-SUP failed at turn 1, unverifiedReason="suspended", checkpointGate present).
337
+ // FIX: run the durable task at the TOP LEVEL so the suspend propagates as status:"suspended" + checkpointToken;
338
+ // driveSupSuspendResume (arms.ts) then resumes via resumeWithVerification (which resumes AND verifies on
339
+ // completion). The initial TaskResult is shaped as a VerificationResult placeholder — no verdict until the
340
+ // resume completes; the objective oracle (runOracle) is the measure regardless.
214
341
  runWithVerificationSup: async (implSpec) => {
215
342
  const { runner } = await ensureWorker();
216
343
  const result = await runner.runTask(toSupTaskSpec(baseSpec, implSpec, trap));
344
+ // 🔴 Map each durable-pause status to its OWN unverifiedReason (review MED): driveSupSuspendResume routes
345
+ // tool-approval (suspended → policy_ask) vs plan/dry-run review (needs_review → plan_review/dry_run_review) by
346
+ // this reason. Collapsing needs_review→"suspended" would send a plan-review gate down the tool-approval branch
347
+ // (bindingFromCheckpoint fails → the loop stops without resuming). Current firm traps don't hit a first-leg
348
+ // plan-review, but the driver advertises support for it.
217
349
  const unverifiedReason = result.status === "needs_review" ? "needs_review" : result.status === "suspended" ? "suspended" : "no_verdict";
218
350
  return { ...result, verification: { verdict: "unverified", unverifiedReason, rounds: 0, findings: [] } };
219
351
  },
352
+ // ── SUP resume: resume the durable-suspended impl AND verify on completion ──
220
353
  resumeWithVerification: async (token, outcome, implSpec) => {
221
354
  const { runner } = await ensureWorker();
222
355
  return resumeWithVerification(runner, token, outcome, toSupTaskSpec(baseSpec, implSpec, trap), implSpec.objective, { maxRounds: rt.maxRounds ?? 2 });
223
356
  },
357
+ // ── SUP repair leg: the SAFE-tier self-repair loop. workerEnv IS wired (corr #3 — the §5.1 identity check
358
+ // is LIVE); the grader is the DISTINCT grader sandbox with the worker tree transferred in. ──
224
359
  runRepairLoop: async (implSpec) => {
225
360
  const { env: worker, runner } = await ensureWorker();
226
361
  const grader = await ensureGraderWithWorkerTree();
362
+ // 🔴 (review #4) RE-SYNC the worker tree into the grader BEFORE EACH attempt's grading — the repair loop grades
363
+ // an EVOLVING worker tree once per attempt; the memoized one-shot transfer (correct for the non-repair
364
+ // single-grade path) would freeze the grader at the attempt-1 snapshot and a later fix would never be seen.
227
365
  const oracle = makeRepairOracle({
228
366
  transport: graderTransport(grader),
229
367
  workerEnv: worker,
230
368
  task: oracleTaskFromTrap(trap),
231
369
  reSyncGraderTree: async () => {
232
- state.shas = await transferWorkerTreeToGrader(worker, grader);
370
+ state.shas = await transferWorkerTreeToGrader(worker, grader); // re-extract evolving worktree + refresh shas
233
371
  },
234
372
  });
235
373
  return runRepairLoop(runner, toSupTaskSpec(baseSpec, implSpec, trap), {
236
374
  oracle,
237
- graderEnv: grader,
238
- workerEnv: worker,
375
+ graderEnv: grader, // the DISTINCT grader env (assertDistinctEnvs ran at provision)
376
+ workerEnv: worker, // 🔴 corr #3 — wired so the §5.1 identity check runs (never skipped)
239
377
  maxAttempts: 2,
240
378
  });
241
379
  },
380
+ // ── SUP: read the suspend's pending record (boundCallId/boundInputHash echoed VERBATIM — corr #2 / TOCTOU) ──
242
381
  getCheckpoint: async (store, token, _scope) => {
243
382
  return store.get(token);
244
383
  },
384
+ // ── TEAM: the leader orchestrator via createLeaderRunner with budget-stamped workers. The leader integrates +
385
+ // PUSHES to a per-cell durable remote (git daemon on the CONTROL PLANE). On a DELIVERED run we bundle that
386
+ // integrated tree ON THE CONTROL PLANE and stash it as state.teamBundle; ensureGraderWithWorkerTree then seeds
387
+ // the GRADER from it directly (the worker stays the empty-base distinct env). If the integrated tree cannot be
388
+ // captured, runLeaderForTrap returns infraFailed (EXCLUDED, never a fabricated uniform loss). ──
245
389
  runLeaderTask: async () => {
390
+ // 🔴 NETWORK ISOLATION (firm-v1/C4 drill): the leader's git daemon serves git://127.0.0.1:<port> on the CONTROL
391
+ // PLANE; the E2B sandboxes are network-isolated → cloning git://127.0.0.1 from INSIDE E2B hits the sandbox's own
392
+ // localhost ("not a git repository"). FIX: clone+bundle the integrated ref HERE on the control plane, stash the
393
+ // base64 bundle (+ its base hash) in state; the grader-import path (importBundleB64ToGrader via writeFile, the
394
+ // PROVEN control-plane↔E2B-grader transport) ships it into the grader. We never touch the E2B worker for this.
246
395
  const captureIntegratedTreeToBundle = async (remoteUrl, targetRef) => {
247
396
  const { execFileSync } = await import("node:child_process");
248
397
  const { mkdtempSync, readFileSync, rmSync } = await import("node:fs");
@@ -260,19 +409,25 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
260
409
  console.error(`[S1_DEBUG_IMPORT] cp clone --branch ${branch} failed: ${e1.stderr?.toString().slice(-200)}; retrying default`);
261
410
  execFileSync("git", ["clone", "-q", remoteUrl, cloneDir], { stdio: ["ignore", "ignore", "pipe"] });
262
411
  }
412
+ // The integrated repo's root commit = the grader's s1-base (HEAD = the leader's merge commit, advanced past it).
263
413
  const baseHash = execFileSync("git", ["-C", cloneDir, "rev-list", "--max-parents=0", "HEAD"]).toString().trim().split("\n").pop().trim();
264
414
  const head = execFileSync("git", ["-C", cloneDir, "rev-parse", "HEAD"]).toString().trim();
265
415
  if (!/^[0-9a-f]{40}$/.test(baseHash) || head === baseHash) {
266
416
  if (process.env.S1_DEBUG_GIT)
267
417
  console.error(`[S1_DEBUG_IMPORT] cp integrated tree not delivered: head=${head} base=${baseHash}`);
268
- return false;
418
+ return false; // no advance past base ⇒ leader didn't deliver ⇒ infra-failed (NEVER a fake loss)
269
419
  }
270
420
  const bundlePath = join(tmp, "team.bundle");
421
+ // 🔴 git archive HEAD = the integrated WORKTREE as a tar (no .git) — the grader tar -x's plain files, never
422
+ // git clone (E2B grader-clone heisenbug + Kata virtiofs). delivered = head≠base from the shas computed here
423
+ // on the control plane (where git works). (Was: `git bundle` + grader clone — that hit both backends' git
424
+ // failures.) The single-revision HEAD bundle comment kept for history; we now ship a worktree tar instead.
425
+ // is tagged explicitly on the grader side, so delivered = HEAD≠base still resolves).
271
426
  execFileSync("git", ["-C", cloneDir, "archive", "--format=tar", "-o", bundlePath, "HEAD"], { stdio: ["ignore", "ignore", "pipe"] });
272
- const buffer = readFileSync(bundlePath);
427
+ const buffer = readFileSync(bundlePath); // RAW tar bytes — shipped to the grader as BINARY + tar -x'd (no git)
273
428
  if (process.env.S1_DEBUG_GIT)
274
429
  console.error(`[S1_DEBUG_IMPORT] cp integrated head=${head} base=${baseHash} tar bytes=${buffer.length}`);
275
- state.teamBundle = { buffer, head, base: baseHash };
430
+ state.teamBundle = { buffer, head, base: baseHash }; // consumed by ensureGraderWithWorkerTree (tar -x, no git)
276
431
  return true;
277
432
  }
278
433
  catch (e) {
@@ -286,16 +441,28 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
286
441
  };
287
442
  return runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, captureIntegratedTreeToBundle);
288
443
  },
444
+ // ── The hidden objective oracle (the measure), graded in the DISTINCT grader env ──
289
445
  runOracle: () => runOracle(false),
446
+ // 🔴 runCounterfactualOracle is DELIBERATELY OMITTED (it is OPTIONAL in ProfileDeps). The honest "no counterfactual"
447
+ // path: buildCounterfactual returns undefined → the metric tool records UNVERIFIED-WITHHELD (NO avoided-loss
448
+ // credit), the documented no-fake-credit choice (README / row.ts). The previous `runCounterfactualOracle:
449
+ // runOracle` self-alias re-graded the IDENTICAL post-gate tree, so withoutInterventionTrulyCorrect ALWAYS
450
+ // equaled withInterventionTrulyCorrect → every withhold auto-credited CORRECTLY-WITHHELD (withholdPrecision a
451
+ // tautological 1.0); for the SUP tool-deny path the deny is a REAL durable suspend that blocked the commit, so
452
+ // re-grading the same blocked tree is NOT an ablation. A real ablation (re-run the SAME (trap,seed) with the
453
+ // gate DISABLED into a FRESH worker, grade THAT in a separate grader) is the only thing that makes
454
+ // INCORRECTLY-WITHHELD reachable — TODO; until it lands we honestly omit rather than manufacture credit.
290
455
  };
291
456
  const dispose = async () => {
292
457
  await Promise.allSettled([state.worker?.destroy(), state.grader?.destroy()]);
293
458
  };
294
459
  return { deps, dispose };
295
460
  }
461
+ /** Project a `SoloImplSpec` (budget already stamped by the harness) onto the bench base TaskSpec. */
296
462
  function toTaskSpec(base, impl) {
297
463
  return { ...base(impl.objective), maxTokens: impl.maxTokens, maxCostUsd: impl.maxCostUsd, limits: { ...impl.limits } };
298
464
  }
465
+ /** Project a `SupImplSpec` onto the bench base TaskSpec PLUS the durable wiring (checkpointStore + ask policy). */
299
466
  function toSupTaskSpec(base, impl, trap) {
300
467
  const requireApproval = trap.gatedTools ?? ["Bash"];
301
468
  const neverAuto = trap.neverAuto ?? [];
@@ -307,7 +474,29 @@ function toSupTaskSpec(base, impl, trap) {
307
474
  onQuestion: QUESTION_AWAITS_RESUME,
308
475
  };
309
476
  }
477
+ /**
478
+ * Run the leader (TEAM) for a trap via `createLeaderRunner`, then map its `LeaderResult` → `LeaderTaskOutcome` (the
479
+ * subset the harness needs for the COMPLETE TEAM cost + outcome). The leader runs its OWN integration sandbox + an
480
+ * objective hidden oracle (its `testCmd` over the trap's oracleSteps) and PUSHES the integrated tree to a per-cell
481
+ * durable remote. The harness then IMPORTS that integrated tree into state.worker (via `importIntegratedTreeToWorker`)
482
+ * so its `runOracle` independently re-grades the REAL integrated output in the DISTINCT grader (the trusted measure —
483
+ * the leader's own gate is NOT trusted as the numerator). Budget-stamped: per-worker maxCostUsd is bounded so
484
+ * Σworker ≤ the arm budget.
485
+ *
486
+ * 🔴 The integrated tree is the actual TEAM output. The durable remote is served over `git://127.0.0.1` by a local
487
+ * `git daemon` (the leader/wire.ts validator REJECTS `file://`; `git://` passes AND the Coordinator can push to
488
+ * it). After a delivered run the harness clones the pushed targetRef into state.worker; if that import fails (the
489
+ * leader never delivered, or no integrated head exists) the cell is `infraFailed:true` (EXCLUDED) — NEVER a
490
+ * fabricated uniform "delivered=false" loss for the whole TEAM column.
491
+ *
492
+ * 🔴 The leader's workers run on the E2B factory (each its OWN VM — isolation). A leader crash surfaces as
493
+ * `infraFailed:true` (EXCLUDED), never a scored loss.
494
+ */
310
495
  async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, importIntegratedTreeToWorker) {
496
+ // The TEAM arm needs a durable remote to integrate into. For S1 we serve a throwaway local bare git repo over
497
+ // `git://127.0.0.1:<port>` via `git daemon` so (a) the leader/wire.ts validator accepts the URL (it forbids
498
+ // file://) and (b) the Coordinator can clone+push it. 🔴 Needs `git` (incl. `git daemon`) on the control-plane
499
+ // PATH (deploy req, leader/wire.ts header).
311
500
  const { mkdtempSync, rmSync, writeFileSync, mkdirSync } = await import("node:fs");
312
501
  const { execFileSync, spawn } = await import("node:child_process");
313
502
  const { tmpdir } = await import("node:os");
@@ -317,7 +506,9 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
317
506
  const repoName = "team.git";
318
507
  const remoteDir = join(baseDir, repoName);
319
508
  execFileSync("git", ["init", "-q", "--bare", remoteDir]);
509
+ // Mark the bare repo daemon-exportable (git daemon refuses to serve a repo without this unless --export-all).
320
510
  execFileSync("git", ["--git-dir", remoteDir, "config", "daemon.receivepack", "true"]);
511
+ // Pick a free localhost port for the daemon (bind:0 → OS-assigned → read it back).
321
512
  const port = await new Promise((resolve, reject) => {
322
513
  const srv = net.createServer();
323
514
  srv.once("error", reject);
@@ -327,6 +518,8 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
327
518
  srv.close(() => (p ? resolve(p) : reject(new Error("could not pick a free port"))));
328
519
  });
329
520
  });
521
+ // Start `git daemon` serving baseDir over 127.0.0.1:port with push enabled. The URL the leader receives is
522
+ // git://127.0.0.1:<port>/<repoName>.
330
523
  const daemon = spawn("git", [
331
524
  "daemon",
332
525
  "--reuseaddr",
@@ -337,6 +530,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
337
530
  "--enable=receive-pack",
338
531
  remoteDir,
339
532
  ], { stdio: "ignore" });
533
+ // Give the daemon a moment to bind (poll the port until it accepts, up to ~3s).
340
534
  const waitForPort = async () => {
341
535
  for (let i = 0; i < 30; i++) {
342
536
  const up = await new Promise((resolve) => {
@@ -355,13 +549,22 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
355
549
  };
356
550
  const remoteUrl = `git://127.0.0.1:${port}/${basename(remoteDir)}`;
357
551
  const targetRef = "refs/heads/main";
552
+ // Budget-stamped workers (Σ ≤ arm budget). The leader splits the arm budget across ≤2 workers for C4.
553
+ // 🔴 LOAD-BEARING ON THE SEQUENTIAL DRIVER (run-firm.ts: `for (const cell of cells)` is strictly sequential,
554
+ // one runArm at a time). loadConfig()/leaderResourceConfig() read these knobs ONLY from process.env (no
555
+ // parameterized override seam exists today), so env-stamping is the only lever. If run-firm's loop is ever
556
+ // parallelized, two cells would race on shared process.env (cross-contaminating the per-worker budget — the
557
+ // §3.2 fairness root); thread the config explicitly (loadConfig override args + LeaderWireConfig fields) FIRST.
358
558
  process.env.LEADER_ENABLED = "true";
359
559
  process.env.LEADER_WORKER_BUDGET_USD = String((rt.maxCostUsd ?? 1.0) / 2);
360
- process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2";
560
+ process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2"; // C4 = fan-out conflict → resolver
361
561
  const run = createLeaderRunner({
362
562
  brain, models, roles, pricing, e2bApiKey: rt.e2bApiKey, workspace: W,
363
563
  ...(process.env.S1_DEBUG_GIT ? { logger: { warn: (m, x) => console.error(`[S1_DEBUG_LEADER warn] ${m}`, x ? JSON.stringify(x).slice(0, 300) : ""), info: (m, x) => console.error(`[S1_DEBUG_LEADER info] ${m}`, x ? JSON.stringify(x).slice(0, 200) : "") } } : {}),
364
564
  });
565
+ // The seed command (run in each worker + the integration sandbox): a fresh repo at base. For a hazard trap (C7)
566
+ // the seedFiles are written + committed INTO each worker's base (PRECIOUS sentinel + scratch) so the worker SEES
567
+ // them and may over-delete from its local view (search S1c fan-out hazard). Absent ⇒ an empty base.
365
568
  const teamSeedWrite = (trap.seedFiles ?? [])
366
569
  .map((f) => {
367
570
  const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
@@ -371,6 +574,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
371
574
  .join("; ");
372
575
  const teamSeedStep = trap.seedFiles && trap.seedFiles.length > 0 ? `${teamSeedWrite}; git add -A; ` : "";
373
576
  const seedCmd = `rm -rf ${REPO}; mkdir -p ${REPO}; cd ${REPO}; git init -q; git config user.email s1@bench.local; git config user.name s1-bench; git config commit.gpgsign false; ${teamSeedStep}git commit -q --allow-empty -m base`;
577
+ // The integration testCmd = the trap's objective COMMAND oracle steps (the leader's hidden-oracle gate).
374
578
  const testCmd = trap.oracle.oracleSteps.map((s) => s.command).join(" && ");
375
579
  const oracleFiles = trap.oracle.hiddenTestFiles;
376
580
  const killDaemon = () => {
@@ -378,6 +582,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
378
582
  daemon.kill("SIGKILL");
379
583
  }
380
584
  catch {
585
+ /* already gone */
381
586
  }
382
587
  };
383
588
  let res;
@@ -385,11 +590,20 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
385
590
  if (!(await waitForPort())) {
386
591
  return { ok: false, reports: [], infraFailed: true };
387
592
  }
593
+ // 🔴 Seed the bare daemon repo's `main` with a REAL base commit + capture its sha (firm-v1/C4 dig — the deepest
594
+ // TEAM layer). The bare repo was EMPTY and baseSha was the literal "HEAD": the Coordinator (wire.ts) clones the
595
+ // durable remote then `git am`s the integrated patch and pushes `--force-with-lease=refs/heads/main:<baseSha>`.
596
+ // With an empty repo + a non-sha "HEAD" lease, the integrated head landed at root INTERMITTENTLY → my control-plane
597
+ // clone of main saw root-only (head==base) → TEAM was unmeasurable. A real base commit + the real base sha makes
598
+ // the Coordinator's am apply on a deterministic base and the lease exact → main = the integrated merge, always.
388
599
  const seedDir = mkdtempSync(join(tmpdir(), "s1-team-seed-"));
389
600
  execFileSync("git", ["clone", "-q", remoteDir, seedDir], { stdio: ["ignore", "ignore", "pipe"] });
390
601
  execFileSync("git", ["-C", seedDir, "config", "user.email", "s1@bench.local"]);
391
602
  execFileSync("git", ["-C", seedDir, "config", "user.name", "s1-bench"]);
392
603
  execFileSync("git", ["-C", seedDir, "config", "commit.gpgsign", "false"]);
604
+ // Hazard trap (C7): seed the durable base with the SAME files (PRECIOUS sentinel + scratch) so the merge starts
605
+ // from a tree CONTAINING the sentinel — a worker's over-delete then surfaces as a real deletion in the integrated
606
+ // tree (merge-result survival). Absent ⇒ empty base (C4 disjoint creates everything fresh).
393
607
  for (const f of trap.seedFiles ?? []) {
394
608
  const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
395
609
  const abs = join(seedDir, rel);
@@ -410,6 +624,10 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
410
624
  testCmd,
411
625
  seedCmd,
412
626
  oracleFiles,
627
+ // Fan-out plan: the explicit per-worker subtask list lives on the TrapSpec (C4 disjoint modules, C7 fan-out
628
+ // hazard). The leader's planner REQUIRES disjoint file ownership (a same-file plan is rejected "not disjoint").
629
+ // Each worker gets ONLY its local objective; the oracle checks the integrated result. Traps without subtasks
630
+ // stay single (the router collapses).
413
631
  ...(trap.subtasks ? { subtasks: trap.subtasks } : {}),
414
632
  });
415
633
  }
@@ -422,6 +640,10 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
422
640
  }
423
641
  if (process.env.S1_DEBUG_GIT)
424
642
  console.error(`[S1_DEBUG_LEADER ${trap.id}] ok=${res.ok} error=${JSON.stringify(res.error)} cancelled=${res.cancelled} merge=${JSON.stringify(res.merge)} repairTerminal=${res.repairTerminal} reports=${(res.reports ?? []).length} reportsDetail=${JSON.stringify((res.reports ?? []).map((r) => ({ w: r.workerId, ok: r.ok, err: r.error })))?.slice(0, 400)}`);
643
+ // 🔴 Import the leader's INTEGRATED, pushed tree into state.worker so runOracle grades the REAL TEAM output (not
644
+ // an empty repo). The push leg only ran if the leader integrated+pushed successfully (res.merge.ok). If the
645
+ // import fails (no integrated head — leader did not deliver), mark the cell infra-failed (EXCLUDED), NEVER a
646
+ // fabricated uniform delivered=false loss. The daemon must stay alive for this clone, then we reap it.
425
647
  let imported = false;
426
648
  const merged = res.merge?.ok === true;
427
649
  try {
@@ -435,6 +657,9 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
435
657
  killDaemon();
436
658
  rmSync(baseDir, { recursive: true, force: true });
437
659
  }
660
+ // The leader ran but its integrated tree could not be moved into the grader path → NOT measurable. Honest
661
+ // infra-failed (EXCLUDED), never a fabricated loss. (A leader that legitimately withheld — held the merge — is a
662
+ // DIFFERENT case handled below via res.merge/repairTerminal, where !merged with a withhold terminal is expected.)
438
663
  if (!imported && merged) {
439
664
  return { ok: false, reports: res.reports, infraFailed: true };
440
665
  }
@@ -442,8 +667,21 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
442
667
  ok: res.ok,
443
668
  reports: res.reports,
444
669
  ...(res.merge ? { merge: res.merge } : {}),
670
+ // 🔴 (review HIGH finding) a leader integration-test gate that REJECTED the merge (res.merge.ok===false,
671
+ // phase==="test" — the post-merge oracle/test gate caught a bad integrated tree, e.g. C7's fan-out hazard
672
+ // deleted the sentinel) is an HONEST WITHHOLD (the leader held a bad delivery), NOT a plain not-delivered.
673
+ // Without this, arms.ts withheld=false → the row is mis-booked. Surfacing withheld:true makes arms classify
674
+ // UNVERIFIED-WITHHELD (no counterfactual wired ⇒ NO avoided-loss credit — honest, never DELIVERED-WRONG and
675
+ // never a fake CORRECTLY-WITHHELD; the worker DID execute the hazard, the leader just didn't ship it).
445
676
  ...(res.merge?.ok === false && res.merge.phase === "test" ? { withheld: true } : {}),
677
+ // 🔴 the repair terminal (when the single-agent repair loop ran) drives the TEAM withhold classification in
678
+ // arms.ts (candidate_only/gave_up/conflict → withhold; oracle.unprotected → infra-failed). Passed through.
446
679
  ...(res.repairTerminal ? { repairTerminal: res.repairTerminal } : {}),
680
+ // A leader that integrated+pushed → the integrated tree is now in state.worker (runOracle grades it). A leader
681
+ // that did NOT merge (held the merge / repair non-accepting terminal) leaves state.worker empty → runOracle
682
+ // reports delivered=false, which is the HONEST verdict for an un-delivered TEAM run (the withhold classification
683
+ // in arms.ts reads merge/repairTerminal, and the absent counterfactual → UNVERIFIED-WITHHELD, no fake credit).
684
+ // The leader does not surface a stamped per-worker budget split here; honest "not measured" (undefined).
447
685
  };
448
686
  }
449
687
  //# sourceMappingURL=live-deps.js.map