humanish 0.106.1 → 0.107.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 (453) hide show
  1. package/AGENTS.md +4 -4
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +14 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -8
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +30 -3
  16. package/dist/actors/codex/qualified-versions.js +50 -5
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +9 -7
  45. package/dist/actors/local-agent/cli.js +1 -1
  46. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  47. package/dist/actors/scripted-browser/journey.js +15 -4
  48. package/dist/actors/scripted-browser/steps.js +18 -0
  49. package/dist/actors/scripted-browser/types.d.ts +11 -1
  50. package/dist/actors/stop-conditions.js +1 -3
  51. package/dist/analysis/automatic-completion.d.ts +13 -8
  52. package/dist/analysis/automatic-completion.js +14 -8
  53. package/dist/analysis/automatic-config.d.ts +1 -1
  54. package/dist/analysis/automatic-config.js +2 -2
  55. package/dist/analysis/automatic.d.ts +10 -4
  56. package/dist/analysis/automatic.js +17 -13
  57. package/dist/analysis/diagnostics.d.ts +23 -0
  58. package/dist/analysis/diagnostics.js +112 -0
  59. package/dist/analysis/evidence-sources.js +2 -2
  60. package/dist/analysis/evidence.js +6 -6
  61. package/dist/analysis/execute.d.ts +7 -1
  62. package/dist/analysis/execute.js +39 -12
  63. package/dist/analysis/job.d.ts +8 -5
  64. package/dist/analysis/job.js +15 -14
  65. package/dist/analysis/load.d.ts +1 -1
  66. package/dist/analysis/load.js +5 -5
  67. package/dist/analysis/provider.d.ts +9 -1
  68. package/dist/analysis/restricted-codex.d.ts +2 -0
  69. package/dist/analysis/restricted-codex.js +10 -1
  70. package/dist/analysis/service.d.ts +2 -0
  71. package/dist/analysis/service.js +31 -12
  72. package/dist/analysis/sharing.d.ts +2 -2
  73. package/dist/analysis/sharing.js +5 -5
  74. package/dist/analysis/store-executions.d.ts +5 -5
  75. package/dist/analysis/store-executions.js +12 -12
  76. package/dist/analysis/store.d.ts +4 -4
  77. package/dist/analysis/store.js +13 -13
  78. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  79. package/dist/cli/commands/analysis-signals.js +4 -1
  80. package/dist/cli/commands/analyze.js +4 -2
  81. package/dist/cli/commands/comms.js +8 -1
  82. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  83. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  84. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  85. package/dist/cli/commands/lab-route-preview.js +3 -4
  86. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  87. package/dist/cli/commands/lab-route-run.js +6 -2
  88. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  89. package/dist/cli/commands/lab-route-scripted.js +0 -1
  90. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  91. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  92. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  93. package/dist/cli/commands/lab-route-terminal.js +0 -1
  94. package/dist/cli/commands/lab-run.js +76 -45
  95. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  96. package/dist/cli/commands/lab.js +12 -6
  97. package/dist/cli/commands/observe.js +22 -0
  98. package/dist/cli/commands/run-signals.d.ts +30 -0
  99. package/dist/cli/commands/run-signals.js +146 -0
  100. package/dist/cli/commands/runs.js +10 -8
  101. package/dist/cli/commands/watch.js +12 -10
  102. package/dist/cli/doctor.d.ts +3 -0
  103. package/dist/cli/doctor.js +10 -2
  104. package/dist/cli/io.d.ts +5 -4
  105. package/dist/cli/io.js +12 -8
  106. package/dist/cli/program.js +3 -3
  107. package/dist/cli/renamed-options.d.ts +11 -0
  108. package/dist/cli/renamed-options.js +18 -0
  109. package/dist/cli/telemetry.d.ts +2 -2
  110. package/dist/cli/telemetry.js +1 -1
  111. package/dist/comms/capture-surface.d.ts +1 -1
  112. package/dist/comms/catch-host.d.ts +1 -1
  113. package/dist/comms/connections.js +4 -4
  114. package/dist/comms/external-evidence.d.ts +27 -0
  115. package/dist/comms/external-evidence.js +93 -0
  116. package/dist/comms/lease-store.js +7 -7
  117. package/dist/comms/types.js +1 -1
  118. package/dist/evidence/browser-hygiene.d.ts +1 -1
  119. package/dist/evidence/browser-hygiene.js +1 -1
  120. package/dist/evidence/redaction.js +1 -1
  121. package/dist/evidence/secret-scrub.d.ts +9 -0
  122. package/dist/evidence/secret-scrub.js +96 -0
  123. package/dist/feedback/draft.js +7 -9
  124. package/dist/feedback/export-bundle.js +4 -4
  125. package/dist/feedback/export.js +9 -9
  126. package/dist/feedback/feedback.d.ts +1 -1
  127. package/dist/index.d.ts +3 -6
  128. package/dist/index.js +3 -6
  129. package/dist/keys/key-resolution.d.ts +3 -1
  130. package/dist/keys/key-resolution.js +18 -16
  131. package/dist/lab/adapter-extension.d.ts +28 -6
  132. package/dist/lab/adapter-extension.js +65 -126
  133. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  134. package/dist/lab/adapter-scorer-loader.js +24 -0
  135. package/dist/lab/composition-rules.js +20 -20
  136. package/dist/lab/config.js +28 -26
  137. package/dist/lab/device-presets.d.ts +2 -2
  138. package/dist/lab/discover.js +1 -3
  139. package/dist/lab/doctor.d.ts +44 -9
  140. package/dist/lab/doctor.js +149 -41
  141. package/dist/lab/init-plan.js +1 -3
  142. package/dist/lab/keys.js +1 -1
  143. package/dist/lab/lab-deps.d.ts +85 -0
  144. package/dist/lab/lab-deps.js +4 -0
  145. package/dist/lab/parse/actors.js +8 -7
  146. package/dist/lab/parse/comms.js +3 -2
  147. package/dist/lab/parse/execution.js +3 -2
  148. package/dist/lab/parse/subject-state.js +2 -1
  149. package/dist/lab/parse/subject.js +2 -1
  150. package/dist/lab/parse/values.d.ts +0 -1
  151. package/dist/lab/parse/values.js +0 -3
  152. package/dist/lab/persona-resolve.d.ts +3 -3
  153. package/dist/lab/persona-resolve.js +4 -4
  154. package/dist/lab/persona.js +1 -3
  155. package/dist/lab/plan-base.d.ts +0 -2
  156. package/dist/lab/plan-base.js +6 -4
  157. package/dist/lab/plan-participants.d.ts +5 -5
  158. package/dist/lab/plan-participants.js +2 -2
  159. package/dist/lab/plan-types.d.ts +22 -4
  160. package/dist/lab/plan.d.ts +3 -11
  161. package/dist/lab/plan.js +18 -42
  162. package/dist/lab/preflight-result.js +0 -2
  163. package/dist/lab/preflight.d.ts +0 -3
  164. package/dist/lab/preflight.js +1 -1
  165. package/dist/lab/requirements.d.ts +20 -0
  166. package/dist/lab/requirements.js +54 -0
  167. package/dist/lab/route-inputs.d.ts +23 -12
  168. package/dist/lab/route-inputs.js +48 -51
  169. package/dist/lab/routing.d.ts +19 -24
  170. package/dist/lab/routing.js +14 -47
  171. package/dist/lab/run-lab-events.d.ts +6 -11
  172. package/dist/lab/run-lab-events.js +3 -11
  173. package/dist/lab/run-lab-homes.d.ts +64 -0
  174. package/dist/lab/run-lab-homes.js +3 -0
  175. package/dist/lab/run-lab-options.d.ts +12 -66
  176. package/dist/lab/run-lab-options.js +45 -275
  177. package/dist/lab/summary.d.ts +9 -4
  178. package/dist/lab/summary.js +15 -8
  179. package/dist/lab/types.d.ts +132 -132
  180. package/dist/lab/validation.d.ts +15 -15
  181. package/dist/lab/validation.js +28 -28
  182. package/dist/lab/warnings.js +20 -19
  183. package/dist/observer/artifact.d.ts +1 -1
  184. package/dist/observer/artifact.js +3 -3
  185. package/dist/observer/data.js +2 -2
  186. package/dist/observer/render.js +2 -2
  187. package/dist/observer/run-routes.d.ts +1 -1
  188. package/dist/observer/run-routes.js +5 -5
  189. package/dist/observer/serve.d.ts +17 -0
  190. package/dist/observer/serve.js +34 -3
  191. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  192. package/dist/routes/computer-use/bundle-parts.js +10 -3
  193. package/dist/routes/computer-use/bundle.d.ts +4 -11
  194. package/dist/routes/computer-use/bundle.js +9 -15
  195. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  196. package/dist/routes/computer-use/diagnostics.js +1 -1
  197. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  198. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  199. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  200. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  201. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  202. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  203. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  204. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  205. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  206. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  207. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  208. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  209. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  210. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  211. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  212. package/dist/routes/computer-use/external-comms.js +19 -43
  213. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  214. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  215. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  216. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  217. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  218. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  219. package/dist/routes/computer-use/live-flush.js +19 -27
  220. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +12 -11
  221. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  222. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  223. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  224. package/dist/routes/computer-use/local-vm.js +39 -66
  225. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  226. package/dist/routes/computer-use/participant-desktop.js +5 -25
  227. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  228. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  229. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  230. package/dist/routes/computer-use/participant-facts.js +12 -1
  231. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  232. package/dist/routes/computer-use/participant-model.js +49 -25
  233. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  234. package/dist/routes/computer-use/participant-prompt.js +4 -4
  235. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  236. package/dist/routes/computer-use/participant-runs.js +8 -8
  237. package/dist/routes/computer-use/plan.d.ts +21 -29
  238. package/dist/routes/computer-use/plan.js +52 -60
  239. package/dist/routes/computer-use/preflight.d.ts +3 -5
  240. package/dist/routes/computer-use/preflight.js +20 -16
  241. package/dist/routes/computer-use/rerun-selection.js +10 -6
  242. package/dist/routes/computer-use/result.d.ts +1 -1
  243. package/dist/routes/computer-use/result.js +40 -30
  244. package/dist/routes/computer-use/route.d.ts +3 -4
  245. package/dist/routes/computer-use/route.js +21 -19
  246. package/dist/routes/computer-use/self-report.d.ts +2 -2
  247. package/dist/routes/computer-use/self-report.js +4 -4
  248. package/dist/routes/computer-use/setup.d.ts +8 -14
  249. package/dist/routes/computer-use/setup.js +96 -72
  250. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  251. package/dist/routes/computer-use/single-bundle.js +20 -25
  252. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  253. package/dist/routes/computer-use/subject-projection.js +20 -19
  254. package/dist/routes/computer-use/types.d.ts +169 -210
  255. package/dist/routes/computer-use/types.js +13 -5
  256. package/dist/routes/preview.js +0 -1
  257. package/dist/routes/scripted/bundle.d.ts +3 -6
  258. package/dist/routes/scripted/bundle.js +11 -16
  259. package/dist/routes/scripted/plan.d.ts +5 -7
  260. package/dist/routes/scripted/plan.js +6 -4
  261. package/dist/routes/scripted/result.d.ts +4 -1
  262. package/dist/routes/scripted/result.js +10 -6
  263. package/dist/routes/scripted/route.js +10 -11
  264. package/dist/routes/scripted/scenario.d.ts +1 -1
  265. package/dist/routes/scripted/scenario.js +1 -1
  266. package/dist/routes/scripted/setup.d.ts +3 -2
  267. package/dist/routes/scripted/setup.js +22 -21
  268. package/dist/routes/scripted/subject.d.ts +8 -3
  269. package/dist/routes/scripted/subject.js +9 -5
  270. package/dist/routes/scripted/surface-records.js +1 -1
  271. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  272. package/dist/routes/scripted/surface-sessions.js +4 -4
  273. package/dist/routes/scripted/types.d.ts +19 -36
  274. package/dist/routes/scripted/types.js +1 -2
  275. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  276. package/dist/routes/shared-world/bundle.d.ts +2 -2
  277. package/dist/routes/shared-world/bundle.js +22 -26
  278. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  279. package/dist/routes/shared-world/checkpoints.js +4 -4
  280. package/dist/routes/shared-world/comms.d.ts +5 -4
  281. package/dist/routes/shared-world/comms.js +28 -41
  282. package/dist/routes/shared-world/external-public.d.ts +5 -5
  283. package/dist/routes/shared-world/external-public.js +19 -20
  284. package/dist/routes/shared-world/handoff.d.ts +4 -4
  285. package/dist/routes/shared-world/handoff.js +50 -50
  286. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  287. package/dist/routes/shared-world/lobby-code.js +13 -13
  288. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  289. package/dist/routes/shared-world/{seats.js → participant-specs.js} +43 -48
  290. package/dist/routes/shared-world/plan.d.ts +2 -6
  291. package/dist/routes/shared-world/plan.js +1 -2
  292. package/dist/routes/shared-world/provenance.d.ts +4 -4
  293. package/dist/routes/shared-world/provenance.js +4 -4
  294. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  295. package/dist/routes/shared-world/provisioned.js +46 -40
  296. package/dist/routes/shared-world/result.js +31 -19
  297. package/dist/routes/shared-world/route.js +37 -41
  298. package/dist/routes/shared-world/setup.d.ts +5 -4
  299. package/dist/routes/shared-world/setup.js +12 -14
  300. package/dist/routes/shared-world/types.d.ts +53 -126
  301. package/dist/routes/shared-world/types.js +2 -2
  302. package/dist/routes/terminal/adapter.d.ts +8 -8
  303. package/dist/routes/terminal/adapter.js +28 -125
  304. package/dist/routes/terminal/bundle.d.ts +7 -12
  305. package/dist/routes/terminal/bundle.js +24 -34
  306. package/dist/routes/terminal/credentials.d.ts +2 -2
  307. package/dist/routes/terminal/credentials.js +16 -16
  308. package/dist/routes/terminal/dry-run.d.ts +1 -1
  309. package/dist/routes/terminal/dry-run.js +9 -11
  310. package/dist/routes/terminal/encoding.d.ts +1 -1
  311. package/dist/routes/terminal/encoding.js +2 -2
  312. package/dist/routes/terminal/ledger.d.ts +6 -6
  313. package/dist/routes/terminal/ledger.js +9 -9
  314. package/dist/routes/terminal/live-finish.d.ts +1 -2
  315. package/dist/routes/terminal/live-finish.js +21 -20
  316. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  317. package/dist/routes/terminal/live-sandbox.js +20 -20
  318. package/dist/routes/terminal/participant-text.d.ts +23 -0
  319. package/dist/routes/terminal/participant-text.js +165 -0
  320. package/dist/routes/terminal/plan.d.ts +2 -6
  321. package/dist/routes/terminal/plan.js +13 -9
  322. package/dist/routes/terminal/recorder.d.ts +6 -1
  323. package/dist/routes/terminal/recorder.js +12 -4
  324. package/dist/routes/terminal/result.js +4 -4
  325. package/dist/routes/terminal/route.js +26 -26
  326. package/dist/routes/terminal/runtime.d.ts +3 -2
  327. package/dist/routes/terminal/runtime.js +3 -3
  328. package/dist/routes/terminal/sandbox.d.ts +3 -3
  329. package/dist/routes/terminal/sandbox.js +9 -9
  330. package/dist/routes/terminal/session.js +16 -14
  331. package/dist/routes/terminal/token-usage.js +5 -5
  332. package/dist/routes/terminal/trace.d.ts +5 -8
  333. package/dist/routes/terminal/trace.js +9 -64
  334. package/dist/routes/terminal/types.d.ts +85 -93
  335. package/dist/routes/terminal/types.js +9 -4
  336. package/dist/run/active-runs.d.ts +13 -0
  337. package/dist/run/active-runs.js +12 -0
  338. package/dist/run/bundle-shape.d.ts +2 -1
  339. package/dist/run/bundle-shape.js +4 -4
  340. package/dist/run/bundle.d.ts +63 -56
  341. package/dist/run/bundle.js +9 -8
  342. package/dist/run/cost-summary.js +3 -2
  343. package/dist/run/costs.d.ts +6 -6
  344. package/dist/run/costs.js +10 -10
  345. package/dist/run/detail.d.ts +5 -5
  346. package/dist/run/detail.js +6 -6
  347. package/dist/run/dry-run.js +5 -12
  348. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  349. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  350. package/dist/run/feedback-shape.js +1 -1
  351. package/dist/run/judge.d.ts +16 -4
  352. package/dist/run/judge.js +24 -7
  353. package/dist/run/locate.d.ts +2 -0
  354. package/dist/run/locate.js +3 -1
  355. package/dist/run/outcomes.d.ts +3 -3
  356. package/dist/run/outcomes.js +3 -3
  357. package/dist/run/participant-records.d.ts +2 -2
  358. package/dist/run/participant-records.js +2 -2
  359. package/dist/run/paths.js +1 -1
  360. package/dist/run/pricing.d.ts +19 -9
  361. package/dist/run/pricing.js +30 -18
  362. package/dist/run/projection.d.ts +13 -13
  363. package/dist/run/projection.js +8 -8
  364. package/dist/run/reclaim.d.ts +6 -0
  365. package/dist/run/reclaim.js +13 -3
  366. package/dist/run/results.d.ts +1 -1
  367. package/dist/run/run-index.d.ts +1 -1
  368. package/dist/run/run-index.js +11 -11
  369. package/dist/run/run.d.ts +4 -2
  370. package/dist/run/run.js +9 -5
  371. package/dist/run/sandbox-receipts.d.ts +4 -4
  372. package/dist/run/sandbox-receipts.js +4 -4
  373. package/dist/run/shared-world-evidence.d.ts +47 -47
  374. package/dist/run/shared-world-shape.d.ts +3 -3
  375. package/dist/run/shared-world-shape.js +11 -11
  376. package/dist/run/stats.d.ts +5 -5
  377. package/dist/run/stats.js +8 -8
  378. package/dist/run/status.d.ts +16 -6
  379. package/dist/run/status.js +31 -8
  380. package/dist/run/streams.d.ts +26 -19
  381. package/dist/run/terminal-contract.d.ts +5 -5
  382. package/dist/run/terminal-contract.js +4 -4
  383. package/dist/run/transient-comms-secrets.d.ts +5 -0
  384. package/dist/run/transient-comms-secrets.js +12 -0
  385. package/dist/run-lab.d.ts +36 -34
  386. package/dist/run-lab.js +41 -37
  387. package/dist/subject/desktop-cli.d.ts +1 -1
  388. package/dist/subject/desktop-cli.js +1 -1
  389. package/dist/subject/local-tree-archive.d.ts +1 -1
  390. package/dist/subject/local-tree-archive.js +4 -4
  391. package/dist/subject/local-tree.d.ts +2 -2
  392. package/dist/subject/local-tree.js +1 -1
  393. package/dist/subject/node-bootstrap.d.ts +1 -1
  394. package/dist/subject/node-bootstrap.js +4 -4
  395. package/dist/subject/runtime.js +5 -5
  396. package/dist/subject/serve.js +1 -1
  397. package/dist/subject/steps.d.ts +4 -4
  398. package/dist/subject/steps.js +5 -5
  399. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  400. package/dist/substrates/e2b/cdp-probe.js +1 -1
  401. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  402. package/dist/substrates/e2b/desktop-browser.js +4 -4
  403. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  404. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  405. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  406. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  407. package/dist/substrates/e2b/desktop-media.js +2 -2
  408. package/dist/substrates/e2b/sandbox.js +1 -1
  409. package/dist/substrates/e2b/sdk.js +2 -2
  410. package/dist/substrates/local/runtime-host.d.ts +2 -0
  411. package/dist/substrates/local/runtime-host.js +6 -0
  412. package/dist/tui/actions.d.ts +7 -5
  413. package/dist/tui/actions.js +18 -9
  414. package/dist/tui-app.js +42 -42
  415. package/dist/verify/actor.d.ts +10 -10
  416. package/dist/verify/actor.js +15 -15
  417. package/dist/verify/artifacts.d.ts +1 -1
  418. package/dist/verify/artifacts.js +3 -3
  419. package/dist/verify/costs.d.ts +2 -2
  420. package/dist/verify/costs.js +2 -2
  421. package/dist/verify/liveness.d.ts +1 -1
  422. package/dist/verify/liveness.js +4 -1
  423. package/dist/verify/rerun.d.ts +1 -1
  424. package/dist/verify/rerun.js +1 -1
  425. package/dist/verify/shared-world.js +2 -2
  426. package/dist/verify/verify.js +6 -6
  427. package/docs/README.md +1 -1
  428. package/docs/architecture/actor-contract.md +60 -22
  429. package/docs/architecture/desktop-sessions.md +9 -9
  430. package/docs/architecture/external-public-shared-world.md +5 -0
  431. package/docs/architecture/observer.md +4 -4
  432. package/docs/architecture/restricted-codex-analysis.md +36 -2
  433. package/docs/architecture/state-driven-executor.md +4 -5
  434. package/docs/architecture/task-protocol-support.md +3 -5
  435. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  436. package/docs/contracts/run-bundle.md +10 -8
  437. package/docs/contracts/schemas.md +109 -53
  438. package/docs/contracts/study-analysis.md +24 -0
  439. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  440. package/docs/product/automatic-analysis.md +1 -0
  441. package/docs/ramp/README.md +2 -1
  442. package/package.json +4 -4
  443. package/skills/humanish/SKILL.md +3 -2
  444. package/skills/humanish/agents/openai.yaml +1 -1
  445. package/dist/deprecated.d.ts +0 -90
  446. package/dist/deprecated.js +0 -106
  447. package/dist/lab/bag-overrides.d.ts +0 -18
  448. package/dist/lab/bag-overrides.js +0 -121
  449. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  450. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  451. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  452. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  453. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -1,7 +1,6 @@
1
1
  import { type CuaActorDescriptor } from "../../actors/registry.js";
2
2
  import type { RoutePlanResult, RouteRefusal, SharedWorldPlan } from "../../lab/plan-types.js";
3
3
  import type { LabConfig, LabSubjectState } from "../../lab/types.js";
4
- import type { RunLabProvenance } from "../../run/status.js";
5
4
  import type { ConcurrentSharedWorldLabErrorCode } from "./types.js";
6
5
  /** The error a shared-world lab returns before a run starts. */
7
6
  export interface SharedWorldRefusal extends RouteRefusal<"shared-world", ConcurrentSharedWorldLabErrorCode> {
@@ -17,11 +16,8 @@ export declare function sharedWorldDescriptorOf(actorType: string): CuaActorDesc
17
16
  */
18
17
  export declare function planSharedWorldLab(config: LabConfig, input: {
19
18
  readonly dryRun: boolean;
20
- readonly lab?: RunLabProvenance;
21
- /** A caller's session runner cannot enforce maxOutputTokens. */
22
- readonly hooks?: {
23
- readonly runSession?: unknown;
24
- };
19
+ /** Whether deps.runSession is set: a caller's session runner cannot enforce maxOutputTokens. */
20
+ readonly hasRunSession?: boolean;
25
21
  }): SharedWorldPlanResult;
26
22
  /** The provisioned plane's declared subject state. The external-public plane declares none. */
27
23
  export declare function planeStateOf(plan: SharedWorldPlan): LabSubjectState | undefined;
@@ -55,7 +55,7 @@ export function planSharedWorldLab(config, input) {
55
55
  : concurrentSharedWorldValidationReason(config));
56
56
  if (invalidReason)
57
57
  return refuse(invalid, invalidReason, actor);
58
- if (config.actors[0]?.maxOutputTokens !== undefined && input.hooks?.runSession)
58
+ if (config.actors[0]?.maxOutputTokens !== undefined && input.hasRunSession === true)
59
59
  return refuse(invalid, "maxOutputTokens cannot be enforced by a custom runSession.", actor);
60
60
  const caps = config.execution?.caps;
61
61
  if (!input.dryRun && (caps?.maxUsd !== undefined || caps?.maxTotalUsd !== undefined)) {
@@ -88,7 +88,6 @@ export function planSharedWorldLab(config, input) {
88
88
  throw new Error("a shared-world participant has no caller brain");
89
89
  const base = planBase(config, {
90
90
  dryRun: input.dryRun,
91
- ...(input.lab === undefined ? {} : { lab: input.lab }),
92
91
  analysis,
93
92
  });
94
93
  return {
@@ -2,18 +2,18 @@ import type { RunSubjectProvenance } from "../../run/bundle.js";
2
2
  import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
3
3
  /** Extract the in-sandbox port from the (loopback) serve.url so getHost can expose it. */
4
4
  export declare function servePort(serveUrl: string): number;
5
- /** A getHost URL must be TOKENLESS (no userinfo, no query — no authKey; invariant 1). */
5
+ /** A getHost URL must be tokenless (no userinfo and no query, so no authKey; invariant 1). */
6
6
  export declare function isTokenlessHost(value: string): boolean;
7
- /** sha256-16 of a URL's ORIGIN — the publish-safe host identity persisted in the bundle (the raw
7
+ /** sha256-16 of a URL's origin: the publish-safe host identity persisted in the bundle (the raw
8
8
  * getHost URL embeds the live sandbox id + matches the e2b-URL redaction, so it never lands raw). */
9
9
  export declare function hostOriginDigest(url: string): string;
10
10
  /** A public-safe, human-readable route label for the bundle (host redacted to a placeholder; the
11
11
  * entry path kept). Never contains the raw getHost URL. */
12
12
  export declare function publicSafeRouteLabel(entry: string | undefined): string;
13
13
  /**
14
- * Build the ONE subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
14
+ * Build the one subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
15
15
  * local-tree (archiveSha256 + optional commit/dirty from the once-per-run host-packed archive -
16
- * archiveSha256 IS the pin; there is only ONE archive, so no per-lane unanimity math applies,
16
+ * archiveSha256 is the pin; there is only one archive, so no per-participant unanimity math applies,
17
17
  * unlike the cua fan-out route). Used for both the in-progress and final bundle: the archive
18
18
  * never changes mid-run (packed before any sandbox exists).
19
19
  */
@@ -8,7 +8,7 @@ export function servePort(serveUrl) {
8
8
  return Number(url.port);
9
9
  return url.protocol === "https:" ? 443 : 80;
10
10
  }
11
- /** A getHost URL must be TOKENLESS (no userinfo, no query — no authKey; invariant 1). */
11
+ /** A getHost URL must be tokenless (no userinfo and no query, so no authKey; invariant 1). */
12
12
  export function isTokenlessHost(value) {
13
13
  try {
14
14
  const url = new URL(value);
@@ -18,7 +18,7 @@ export function isTokenlessHost(value) {
18
18
  return false;
19
19
  }
20
20
  }
21
- /** sha256-16 of a URL's ORIGIN — the publish-safe host identity persisted in the bundle (the raw
21
+ /** sha256-16 of a URL's origin: the publish-safe host identity persisted in the bundle (the raw
22
22
  * getHost URL embeds the live sandbox id + matches the e2b-URL redaction, so it never lands raw). */
23
23
  export function hostOriginDigest(url) {
24
24
  try {
@@ -34,9 +34,9 @@ export function publicSafeRouteLabel(entry) {
34
34
  return `[provisioned-subject]${entry ?? "/"}`;
35
35
  }
36
36
  /**
37
- * Build the ONE subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
37
+ * Build the one subject sandbox's provenance (invariant 5): clone (repo + optional commit) or
38
38
  * local-tree (archiveSha256 + optional commit/dirty from the once-per-run host-packed archive -
39
- * archiveSha256 IS the pin; there is only ONE archive, so no per-lane unanimity math applies,
39
+ * archiveSha256 is the pin; there is only one archive, so no per-participant unanimity math applies,
40
40
  * unlike the cua fan-out route). Used for both the in-progress and final bundle: the archive
41
41
  * never changes mid-run (packed before any sandbox exists).
42
42
  */
@@ -3,7 +3,7 @@ import type { RunSubjectStateStepRecord } from "../../run/bundle.js";
3
3
  import type { SharedWorldStateSnapshot } from "../../run/shared-world-evidence.js";
4
4
  import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
5
5
  import type { DetachedTimers } from "../../substrates/detached.js";
6
- import type { SharedWorldLabHooks } from "./types.js";
6
+ import type { LabDeps } from "../../lab/lab-deps.js";
7
7
  import { type ActorRunResult, type SubjectDesktopUsage, type LiveParticipants, type PlaneContext } from "./types.js";
8
8
  /** What the provisioned plane needs besides the shared plane context. */
9
9
  export interface ProvisionedPlaneSetup {
@@ -35,6 +35,7 @@ export interface ProvisionedPlaneOutcome {
35
35
  subjectCommit: string | undefined;
36
36
  subjectSandboxId: string | undefined;
37
37
  subjectKilled: boolean;
38
+ subjectReleaseWarning: string | undefined;
38
39
  subjectDesktop: SubjectDesktopUsage | undefined;
39
40
  getHostUrl: string | undefined;
40
41
  /** Set when the teardown drain wrote a comms thread. */
@@ -47,7 +48,7 @@ export declare function runProvisionedPlane(ctx: PlaneContext, live: LivePartici
47
48
  */
48
49
  export declare function packSubjectTree(cwd: string, config: {
49
50
  readonly subject: Pick<LabConfig["subject"], "localTree">;
50
- }, hooks: SharedWorldLabHooks, scrubKnownValues: (text: string) => string): Promise<{
51
+ }, deps: LabDeps, scrubKnownValues: (text: string) => string): Promise<{
51
52
  ok: true;
52
53
  archive: LocalTreeArchive;
53
54
  buffer: ArrayBuffer;
@@ -1,4 +1,4 @@
1
- // The PROVISIONED-GETHOST plane: the harness provisions ONE subject sandbox (clone or local-tree,
1
+ // The provisioned-getHost plane: the harness provisions one subject sandbox (clone or local-tree,
2
2
  // install/build, seed, serve on 0.0.0.0), exposes it through getHost, probes its state on a
3
3
  // cadence, and runs every seat against that one shared plane. All sandboxes are torn down by exact
4
4
  // id in the plane's finally, never through Sandbox.list.
@@ -10,6 +10,7 @@ import { mapWithConcurrency } from "../../run/concurrency.js";
10
10
  import { provisionCloneSubject } from "../../subject/clone.js";
11
11
  import { provisionLocalTreeSubject } from "../../subject/local-tree.js";
12
12
  import { defaultSharedWorldPhaseSink } from "../../subject/steps.js";
13
+ import { phaseEvent } from "../../lab/run-lab-events.js";
13
14
  import { loadE2BDesktopModule } from "../../substrates/e2b/sdk.js";
14
15
  import { observeDesktopResources, } from "../../substrates/e2b/desktop-resources.js";
15
16
  import { acquireE2BDesktopSandbox, readE2BRelease } from "../../substrates/e2b/sandbox.js";
@@ -19,14 +20,14 @@ import { inboxRecipientFor, participantHasInboxRecipient, } from "../computer-us
19
20
  import { resolveSubjectState } from "../computer-use/subject-projection.js";
20
21
  import { withInboxMission } from "../computer-use/participant-prompt.js";
21
22
  import { planeStateOf } from "./plan.js";
22
- import { runCuaParticipant } from "../computer-use/lanes.js";
23
+ import { runCuaParticipant } from "../computer-use/participant-execution.js";
23
24
  import { buildConcurrentSharedWorldBundle, judgeSharedWorldRun } from "./bundle.js";
24
25
  import { runCheckpointSnapshot } from "./checkpoints.js";
25
26
  import { drainSubjectComms } from "./comms.js";
26
27
  import { buildSubjectProvenance, hostOriginDigest, isTokenlessHost, servePort, } from "./provenance.js";
27
28
  import { SANDBOX_TIMEOUT_BUFFER_MS, SUBJECT_PROVISION_BUDGET_MS, } from "../../substrates/e2b/lifetime.js";
28
29
  import { DEFAULT_STATE_STEP_TIMEOUT_MS } from "../../subject/state.js";
29
- import { resolveActorEntryUrl, participantRunDeps, startParticipantFlush } from "./seats.js";
30
+ import { resolveActorEntryUrl, participantRunDeps, startParticipantFlush, } from "./participant-specs.js";
30
31
  import { CONCURRENT_SHARED_WORLD_PROVIDER_METADATA, } from "./types.js";
31
32
  import { addressedRecipients } from "../../lab/parse/comms.js";
32
33
  /**
@@ -41,12 +42,13 @@ class ObserverGateError extends Error {
41
42
  this.name = "ObserverGateError";
42
43
  }
43
44
  }
44
- /** The ONE subject sandbox and the loops that run against it until teardown. */
45
+ /** The one subject sandbox and the loops that run against it until teardown. */
45
46
  class SubjectPlane {
46
47
  commsInboxUrl;
47
48
  subjectCommit;
48
49
  subjectSandboxId;
49
50
  subjectKilled = false;
51
+ subjectReleaseWarning;
50
52
  getHostUrl;
51
53
  // The subject desktop's host-side span and size, priced in the run's cost estimate.
52
54
  subjectCreatedAtMs;
@@ -57,17 +59,17 @@ class SubjectPlane {
57
59
  subjectAllocation;
58
60
  subjectDesktop;
59
61
  subjectShell;
60
- // The in-sandbox email catch on the ONE subject sandbox (#297); drained at teardown. Undefined
62
+ // The in-sandbox email catch on the one subject sandbox (#297); drained at teardown. Undefined
61
63
  // unless a comms lab declared it.
62
64
  deployedComms;
63
- // Background prober dispose signal (FIX-9: cleared in teardown).
65
+ // Background prober dispose signal, cleared in teardown.
64
66
  proberDisposed = false;
65
67
  releaseDispose = () => { };
66
68
  disposeSignal;
67
69
  proberLoop;
68
70
  snapshotIndex = 0;
69
- // Persona inbox SURFACE (#297 slice B, shared-world): the serve->getHost origin-rewrite map
70
- // (REQUIRED here so the app's loopback verify links resolve to a reachable host), and the
71
+ // Persona inbox surface (#297 slice B, shared-world): the serve->getHost origin-rewrite map
72
+ // (required here so the app's loopback verify links resolve to a reachable host), and the
71
73
  // dedicated surface render loop.
72
74
  commsOriginMap = [];
73
75
  surfaceRenderedCount = 0;
@@ -98,12 +100,12 @@ class SubjectPlane {
98
100
  this.setup.stateSnapshots.push({ timestamp, digest: snapshot.digest });
99
101
  }
100
102
  async acquire() {
101
- const { plan, hooks, env, requestTimeoutMs, timeoutMs } = this.ctx;
103
+ const { plan, deps, env, requestTimeoutMs, timeoutMs } = this.ctx;
102
104
  const { subjectEnvNames, commsEnv } = this.setup;
103
- const subjectModule = await (hooks.loadDesktopModule ?? loadE2BDesktopModule)();
104
- // The ONE subject sandbox: headless service host (no GUI seat). The SUBJECT env is provisioned
105
- // HERE; the actor sandboxes get NONE of it (FIX-10). A custom desktop template (image) is
106
- // honored on BOTH the subject sandbox (here) and every actor sandbox (via runCuaParticipant, which
105
+ const subjectModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
106
+ // The one subject sandbox: headless service host (no GUI seat). The subject env is provisioned
107
+ // here; the actor sandboxes get none of it. A custom desktop template (image) is
108
+ // honored on both the subject sandbox (here) and every actor sandbox (via runCuaParticipant, which
107
109
  // reads the same config); absent keeps the byte-stable Sandbox.create(opts) default. The
108
110
  // receipt is on disk before any work, so `humanish reclaim` can kill it by exact id.
109
111
  const subject = await acquireE2BDesktopSandbox({
@@ -143,18 +145,16 @@ class SubjectPlane {
143
145
  this.subjectSandboxId = subject.allocation.resourceId;
144
146
  this.subjectCreatedAtMs = this.ctx.now();
145
147
  this.subjectResources = await observeDesktopResources(this.subjectDesktop);
146
- if (hooks.prepareDesktop) {
147
- await hooks.prepareDesktop(this.subjectDesktop);
148
- }
148
+ await this.ctx.input.prepareDesktop?.(this.subjectDesktop, { kind: "subject" });
149
149
  }
150
- // Start the in-sandbox email catch BEFORE the subject serve, so the app's send-API base URL
150
+ // Start the in-sandbox email catch before the subject serve, so the app's send-API base URL
151
151
  // (injected into its env at create) resolves the moment it boots. Fail closed if the catch can't
152
152
  // stand up rather than let a comms-declared app silently send real mail to the internet.
153
153
  async deployCatch() {
154
154
  const { commsEmail, commsPort } = this.setup;
155
155
  if (commsEmail && commsPort !== undefined) {
156
- // A SECOND (0.0.0.0) read-only inbox listener on commsPort+1 so the persona — which lives in a
157
- // DIFFERENT sandbox here — can reach the inbox surface via getHost; capture stays loopback.
156
+ // A second (0.0.0.0) read-only inbox listener on commsPort+1 so the persona, which lives in
157
+ // another sandbox here, can reach the inbox surface via getHost; capture stays loopback.
158
158
  this.deployedComms = await deployCommsCatch(this.subjectShell, {
159
159
  port: commsPort,
160
160
  inboxPort: commsPort + 1,
@@ -166,15 +166,19 @@ class SubjectPlane {
166
166
  }
167
167
  }
168
168
  }
169
- // Provision the ONE shared plane: clone + install/build + seed + serve on 0.0.0.0 + probe
170
- // (clone route), or upload/extract the once-per-run packed archive + the SAME shared serve
169
+ // Provision the one shared plane: clone + install/build + seed + serve on 0.0.0.0 + probe
170
+ // (clone route), or upload/extract the once-per-run packed archive + the same shared serve
171
171
  // pipeline (local-tree route).
172
172
  async provision() {
173
- const { plan, hooks, requestTimeoutMs, scrubKnownValues } = this.ctx;
173
+ const { plan, requestTimeoutMs, scrubKnownValues } = this.ctx;
174
174
  const { serve, timers, stateStepRecords } = this.setup;
175
175
  const state = planeStateOf(plan);
176
176
  const subjectShell = this.subjectShell;
177
- const onSubjectPhase = hooks.onPhase ?? defaultSharedWorldPhaseSink;
177
+ const sink = this.ctx.input.deps?.subjectPhaseSink ?? defaultSharedWorldPhaseSink;
178
+ const onSubjectPhase = (event) => {
179
+ sink(event);
180
+ this.ctx.input.emit?.(phaseEvent(event, { kind: "subject" }));
181
+ };
178
182
  if (this.setup.localTreeRoute) {
179
183
  await provisionLocalTreeSubject(subjectShell, {
180
184
  archiveBuffer: this.setup.localTreeArchiveBuffer,
@@ -209,13 +213,13 @@ class SubjectPlane {
209
213
  });
210
214
  }
211
215
  }
212
- // Expose the served port via getHost (FIX-2). Fail closed if the SDK lacks it.
216
+ // Expose the served port via getHost. Fail closed if the SDK lacks it.
213
217
  exposeHost() {
214
218
  const subjectDesktop = this.subjectDesktop;
215
219
  if (typeof subjectDesktop.getHost !== "function") {
216
220
  throw new Error("the installed @e2b/desktop SDK does not expose getHost(port); the concurrent shared-world route requires it to reach the subject plane");
217
221
  }
218
- // getHost returns a BARE host (e.g. "3000-<sandboxId>.e2b.app", no scheme); e2b exposes the
222
+ // getHost returns a bare host (e.g. "3000-<sandboxId>.e2b.app", no scheme); e2b exposes the
219
223
  // port over https. Normalize to a full URL before the tokenless check + before persisting.
220
224
  const rawHost = subjectDesktop.getHost(servePort(this.setup.serve.url));
221
225
  const hostUrl = /^https?:\/\//i.test(rawHost) ? rawHost : `https://${rawHost}`;
@@ -224,12 +228,12 @@ class SubjectPlane {
224
228
  }
225
229
  this.getHostUrl = hostUrl;
226
230
  }
227
- // Persona inbox SURFACE (#297 slice B, shared-world): getHost-expose the read-only inbox listener so
228
- // a persona in a DIFFERENT sandbox can open it; build the serve->getHost origin map (REQUIRED here —
231
+ // Persona inbox surface (#297 slice B, shared-world): getHost-expose the read-only inbox listener so
232
+ // a persona in another sandbox can open it; build the serve->getHost origin map (required here:
229
233
  // the app's loopback verify links must be rewritten to a reachable host); provision the surface
230
- // channel; write the EMPTY inbox up front (so /inbox never 404s); and start a render loop that drains
234
+ // channel; write the empty inbox up front (so /inbox never 404s); and start a render loop that drains
231
235
  // + re-renders on a cadence. The loop shares the prober's dispose signal (disposed together, before
232
- // the teardown evidence drain), and uses a DEDICATED FakeInbox + cursor (independent of that drain).
236
+ // the teardown evidence drain), and uses a dedicated FakeInbox + cursor (independent of that drain).
233
237
  async startInboxSurface() {
234
238
  const { commsEmail } = this.setup;
235
239
  const { requestTimeoutMs } = this.ctx;
@@ -303,7 +307,7 @@ class SubjectPlane {
303
307
  this.disposeSignal,
304
308
  ]);
305
309
  if (timer)
306
- clearTimeout(timer); // FIX-9: no dangling prober timer.
310
+ clearTimeout(timer); // No dangling prober timer.
307
311
  if (this.proberDisposed)
308
312
  break;
309
313
  await this.snapshot().catch(() => undefined);
@@ -311,8 +315,8 @@ class SubjectPlane {
311
315
  })();
312
316
  }
313
317
  /**
314
- * FIX-9: stop the prober, take a final snapshot while the subject is still alive, then tear
315
- * down the ONE subject sandbox BY id (the actor sandboxes are torn down inside runCuaParticipant).
318
+ * Stop the prober, take a final snapshot while the subject is still alive, then tear
319
+ * down the one subject sandbox by id (the actor sandboxes are torn down inside runCuaParticipant).
316
320
  * Returns the comms thread's path when the drain wrote one.
317
321
  */
318
322
  async teardown() {
@@ -345,6 +349,8 @@ class SubjectPlane {
345
349
  this.subjectKilled = reading.released;
346
350
  if (reading.warning)
347
351
  warnings.push(reading.warning);
352
+ if (!reading.released)
353
+ this.subjectReleaseWarning = reading.warning ?? "Subject sandbox release is unconfirmed.";
348
354
  // Without a kill method, or in E2B debug mode, no kill reached E2B, so there is no teardown
349
355
  // time to record.
350
356
  if (released.status !== "unconfirmed" || released.reason !== "release_unavailable")
@@ -385,11 +391,10 @@ async function publishInProgress(plane, ctx, live, setup) {
385
391
  });
386
392
  const snapshotArgs = {
387
393
  plan,
394
+ run: ctx.run,
388
395
  descriptor: ctx.descriptor,
389
- createdAt: ctx.createdAt,
390
396
  dryRun: false,
391
397
  inProgress: true,
392
- runId: ctx.runId,
393
398
  source: ctx.source,
394
399
  actorSpecs: ctx.actorSpecs,
395
400
  actorResults: [],
@@ -417,9 +422,9 @@ async function publishInProgress(plane, ctx, live, setup) {
417
422
  }
418
423
  startParticipantFlush(ctx, live, inProgressBundle);
419
424
  }
420
- // Launch N actor sandboxes CONCURRENTLY, INDEPENDENT (FIX-11: runCuaParticipant + mapWithConcurrency,
421
- // NOT runCuaParticipants — no pipeline gate / fail-fast). Each actor's window is measured on the ONE
422
- // orchestrator clock (FIX-1).
425
+ // Launch N actor sandboxes concurrently and independently (runCuaParticipant + mapWithConcurrency;
426
+ // runCuaParticipants would add a pipeline gate and fail-fast). Each actor's window is measured on the
427
+ // one orchestrator clock.
423
428
  function runParticipants(plane, ctx, live, setup) {
424
429
  const { now } = ctx;
425
430
  const participants = ctx.plan.plane.participants;
@@ -427,7 +432,7 @@ function runParticipants(plane, ctx, live, setup) {
427
432
  const baseActorDeps = participantRunDeps(ctx, live, ctx.scrubKnownValues);
428
433
  return mapWithConcurrency(ctx.actorSpecs, Math.max(1, ctx.concurrency), async (spec, i) => {
429
434
  const route = resolveActorEntryUrl(plane.getHostUrl, participants[i]?.entry);
430
- // Tell this persona its (getHost-reachable) inbox URL — but only when comms is live AND this lane
435
+ // Tell this persona its (getHost-reachable) inbox URL, but only when comms is live and this participant
431
436
  // has a declared recipient it can actually receive mail into (else it would stall on an empty
432
437
  // inbox). Only the in-sandbox catch exists on this plane; the adopter-hosted catch is the
433
438
  // external-public plane's (#387).
@@ -472,6 +477,7 @@ export async function runProvisionedPlane(ctx, live, setup) {
472
477
  subjectCommit: plane.subjectCommit,
473
478
  subjectSandboxId: plane.subjectSandboxId,
474
479
  subjectKilled: plane.subjectKilled,
480
+ subjectReleaseWarning: plane.subjectReleaseWarning,
475
481
  subjectDesktop: plane.desktopUsage(),
476
482
  getHostUrl: plane.getHostUrl,
477
483
  commsArtifactPath,
@@ -481,8 +487,8 @@ export async function runProvisionedPlane(ctx, live, setup) {
481
487
  * Packs the working tree once per run, on the host, for a local-tree subject. Returns the archive,
482
488
  * or the message the run fails with.
483
489
  */
484
- export async function packSubjectTree(cwd, config, hooks, scrubKnownValues) {
485
- const packLocalTree = hooks.packLocalTree ?? defaultPackLocalTree;
490
+ export async function packSubjectTree(cwd, config, deps, scrubKnownValues) {
491
+ const packLocalTree = deps.packLocalTree ?? defaultPackLocalTree;
486
492
  try {
487
493
  const packed = await packLocalTree({
488
494
  root: cwd,
@@ -1,10 +1,10 @@
1
1
  // Finishing a concurrent shared-world run: publishing its bundle, rendering the Observer, and the
2
2
  // lab result with each role's outcome and the one error a run that did not pass reports.
3
3
  import { redactText } from "../../evidence/redaction.js";
4
- import { adapterScoreFailureMessage, applyBrowserAdapterHooks, } from "../../lab/adapter-extension.js";
4
+ import { adapterScoreFailureMessage, applyBrowserScorer } from "../../lab/adapter-extension.js";
5
5
  import { attachObserverRuntimeStreamUrls } from "../../observer/render.js";
6
- import { foldScorerFailures, judgeExecution, OUTCOME_POLICIES, participantHarnessFailed, resultOk, sharedWorldShortfall, } from "../../run/judge.js";
7
- import { participantFactsOf } from "../computer-use/participant-facts.js";
6
+ import { foldScorerFailures, judgeExecution, sandboxCleanupFailure, OUTCOME_POLICIES, participantHarnessFailed, resultOk, sharedWorldShortfall, } from "../../run/judge.js";
7
+ import { participantFactsOf, unreleasedSandboxFailures, } from "../computer-use/participant-facts.js";
8
8
  import { resolveSubjectState } from "../computer-use/subject-projection.js";
9
9
  import { actorRunPassed, buildConcurrentSharedWorldBundle, judgeSharedWorldRun, maxSimultaneousWindows, } from "./bundle.js";
10
10
  import { planeStateOf } from "./plan.js";
@@ -18,6 +18,7 @@ export function emptyPlaneResults() {
18
18
  subjectCommit: undefined,
19
19
  subjectSandboxId: undefined,
20
20
  subjectKilled: false,
21
+ subjectReleaseWarning: undefined,
21
22
  subjectDesktop: undefined,
22
23
  getHostUrl: undefined,
23
24
  publicOriginDigest: undefined,
@@ -85,8 +86,8 @@ function concurrentLabError(args) {
85
86
  if (ok)
86
87
  return undefined;
87
88
  if (handoffTimedOut) {
88
- // Checked BEFORE the observer failure: the host never yielded a /lobby/CODE within the
89
- // deadline (followers failed closed without opening), which is the ROOT CAUSE — and it can
89
+ // Checked before the observer failure: the host never yielded a /lobby/CODE within the
90
+ // deadline (followers failed closed without opening), which is the root cause, and it can
90
91
  // itself make the Observer unable to render a coherent run. Report the distinct, honest
91
92
  // handoff-timeout code rather than a generic observer/run failure.
92
93
  return {
@@ -159,10 +160,12 @@ export function concurrentLabFailure(envelope) {
159
160
  }
160
161
  /**
161
162
  * The run's execution failures: a run error (the handoff, the plane), each seat whose session
162
- * failed in the harness, and an Observer that failed.
163
+ * failed in the harness, each provider whose cleanup is unconfirmed or that reported a disallowed
164
+ * item after its last request, each sandbox whose release is unconfirmed, and an Observer that
165
+ * failed.
163
166
  */
164
167
  function sharedWorldExecutionFailures(args) {
165
- const { runError, actorResults, observer } = args;
168
+ const { runId, runError, actorResults, subject, observer } = args;
166
169
  return [
167
170
  ...(runError === undefined ? [] : [{ kind: "run", message: runError }]),
168
171
  ...actorResults
@@ -179,6 +182,18 @@ function sharedWorldExecutionFailures(args) {
179
182
  message: `${result.spec.planned.id}: ${result.outcome.providerCleanupError}`,
180
183
  },
181
184
  ]),
185
+ ...actorResults.flatMap((result) => result.outcome.providerPolicyError === undefined
186
+ ? []
187
+ : [
188
+ {
189
+ kind: "provider-policy",
190
+ message: `${result.spec.planned.id}: ${result.outcome.providerPolicyError}`,
191
+ },
192
+ ]),
193
+ ...unreleasedSandboxFailures(actorResults.map((result) => result.outcome), runId),
194
+ ...(subject.subjectSandboxId === undefined || subject.subjectKilled
195
+ ? []
196
+ : [sandboxCleanupFailure("subject", subject.subjectReleaseWarning, runId)]),
182
197
  ...(observer.ok
183
198
  ? []
184
199
  : [
@@ -191,7 +206,7 @@ function sharedWorldExecutionFailures(args) {
191
206
  }
192
207
  /** Builds and publishes the bundle, renders the Observer and returns the lab result. */
193
208
  export async function finishConcurrentRun(ctx, live, results, plane) {
194
- const { plan, input, descriptor, hooks, actorSpecs, run, runId, createdAt } = ctx;
209
+ const { plan, input, descriptor, actorSpecs, run, runId } = ctx;
195
210
  const participantCount = plan.plane.participants.length;
196
211
  const { cwd, concurrency, source, seedDigest, receiving, warnings, scrubKnownValues } = ctx;
197
212
  const { dryRun } = plan;
@@ -218,17 +233,15 @@ export async function finishConcurrentRun(ctx, live, results, plane) {
218
233
  }),
219
234
  });
220
235
  const planeCommit = localTreeRoute ? localTreeArchive?.git?.commit : subjectCommit;
221
- // Collect per-actor warnings (each lane's own teardown/raw-screenshot notes).
236
+ // Collect per-actor warnings (each participant's own teardown/raw-screenshot notes).
222
237
  for (const result of actorResults) {
223
238
  warnings.push(...result.outcome.warnings);
224
239
  }
225
240
  const bundleArgs = {
226
- ...(plan.lab === undefined ? {} : { lab: plan.lab }),
241
+ run,
227
242
  plan,
228
243
  descriptor,
229
- createdAt,
230
244
  dryRun,
231
- runId,
232
245
  source,
233
246
  actorSpecs,
234
247
  actorResults,
@@ -249,8 +262,8 @@ export async function finishConcurrentRun(ctx, live, results, plane) {
249
262
  const judgment = judgeSharedWorldRun(bundleArgs);
250
263
  const bundle = buildConcurrentSharedWorldBundle({ ...bundleArgs, judgment });
251
264
  const adapterWarnings = [];
252
- const scorerResult = await applyBrowserAdapterHooks({
253
- hooks,
265
+ const scorerResult = await applyBrowserScorer({
266
+ scorer: input.scorer,
254
267
  bundle,
255
268
  context: {
256
269
  bundle,
@@ -258,13 +271,12 @@ export async function finishConcurrentRun(ctx, live, results, plane) {
258
271
  labId: plan.labId,
259
272
  runId,
260
273
  actor: descriptor.id,
261
- backend: "concurrent-shared-world",
274
+ route: "shared-world",
262
275
  dryRun,
263
- laneCount: participantCount,
276
+ participantCount,
264
277
  },
265
278
  sanitize: (text) => redactText(scrubKnownValues(text)),
266
279
  warnings: adapterWarnings,
267
- hookLabel: "sharedWorldHooks",
268
280
  ...(input.scorerProvenance === undefined ? {} : { scorerProvenance: input.scorerProvenance }),
269
281
  });
270
282
  // The one final verdict fold: scoring can only make the judged verdict stricter.
@@ -276,13 +288,13 @@ export async function finishConcurrentRun(ctx, live, results, plane) {
276
288
  if (observer.ok && live.observer) {
277
289
  attachObserverRuntimeStreamUrls(observer, live.streamUrls);
278
290
  }
279
- // Concurrent "ok": every actor must produce a terminal, engaged PASSED session, and the seats
291
+ // Concurrent "ok": every actor must produce a terminal, engaged, passed session, and the seats
280
292
  // must show the concurrency verify requires of a pass (judgeSharedWorld). This is a
281
293
  // harness/session-credibility gate, not mission-completion proof; a failed actor trace cannot
282
294
  // make the route green just because the harness got a terminal.
283
295
  const adapterFailure = adapterScoreFailureMessage(bundle);
284
296
  const policy = OUTCOME_POLICIES["shared-world"];
285
- const execution = judgeExecution(sharedWorldExecutionFailures({ runError, actorResults, observer }), policy);
297
+ const execution = judgeExecution(sharedWorldExecutionFailures({ runId, runError, actorResults, subject: results, observer }), policy);
286
298
  const ok = resultOk({ judgment, execution, scorerFailures: scorerResult.failures, policy });
287
299
  const overlapProven = !dryRun && judgment.world.overlap;
288
300
  const participantResults = concurrentParticipantResults(actorSpecs, actorResults, dryRun);