humanish 0.106.0 → 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 (459) hide show
  1. package/AGENTS.md +4 -2
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +24 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -6
  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 +31 -4
  16. package/dist/actors/codex/qualified-versions.js +51 -6
  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 +10 -8
  45. package/dist/actors/contract.js +7 -1
  46. package/dist/actors/local-agent/cli.js +1 -1
  47. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  48. package/dist/actors/scripted-browser/journey.js +15 -4
  49. package/dist/actors/scripted-browser/steps.js +18 -0
  50. package/dist/actors/scripted-browser/types.d.ts +11 -1
  51. package/dist/actors/stop-conditions.js +1 -3
  52. package/dist/analysis/automatic-completion.d.ts +13 -8
  53. package/dist/analysis/automatic-completion.js +14 -8
  54. package/dist/analysis/automatic-config.d.ts +1 -1
  55. package/dist/analysis/automatic-config.js +2 -2
  56. package/dist/analysis/automatic.d.ts +10 -4
  57. package/dist/analysis/automatic.js +17 -13
  58. package/dist/analysis/diagnostics.d.ts +23 -0
  59. package/dist/analysis/diagnostics.js +112 -0
  60. package/dist/analysis/evidence-sources.js +2 -2
  61. package/dist/analysis/evidence.js +6 -6
  62. package/dist/analysis/execute.d.ts +7 -1
  63. package/dist/analysis/execute.js +39 -12
  64. package/dist/analysis/job.d.ts +8 -5
  65. package/dist/analysis/job.js +15 -14
  66. package/dist/analysis/load.d.ts +1 -1
  67. package/dist/analysis/load.js +5 -5
  68. package/dist/analysis/provider.d.ts +9 -1
  69. package/dist/analysis/restricted-codex.d.ts +2 -0
  70. package/dist/analysis/restricted-codex.js +10 -1
  71. package/dist/analysis/service.d.ts +2 -0
  72. package/dist/analysis/service.js +31 -12
  73. package/dist/analysis/sharing.d.ts +2 -2
  74. package/dist/analysis/sharing.js +5 -5
  75. package/dist/analysis/store-executions.d.ts +5 -5
  76. package/dist/analysis/store-executions.js +12 -12
  77. package/dist/analysis/store.d.ts +4 -4
  78. package/dist/analysis/store.js +13 -13
  79. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  80. package/dist/cli/commands/analysis-signals.js +4 -1
  81. package/dist/cli/commands/analyze.js +4 -2
  82. package/dist/cli/commands/comms.js +8 -1
  83. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  84. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  85. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  86. package/dist/cli/commands/lab-route-preview.js +3 -4
  87. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  88. package/dist/cli/commands/lab-route-run.js +6 -2
  89. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  90. package/dist/cli/commands/lab-route-scripted.js +0 -1
  91. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  92. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  93. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  94. package/dist/cli/commands/lab-route-terminal.js +0 -1
  95. package/dist/cli/commands/lab-run.js +76 -45
  96. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  97. package/dist/cli/commands/lab.js +12 -6
  98. package/dist/cli/commands/observe.js +22 -0
  99. package/dist/cli/commands/run-signals.d.ts +30 -0
  100. package/dist/cli/commands/run-signals.js +146 -0
  101. package/dist/cli/commands/runs.js +10 -8
  102. package/dist/cli/commands/watch.js +12 -10
  103. package/dist/cli/doctor.d.ts +3 -0
  104. package/dist/cli/doctor.js +10 -2
  105. package/dist/cli/io.d.ts +5 -4
  106. package/dist/cli/io.js +12 -8
  107. package/dist/cli/program.js +3 -3
  108. package/dist/cli/renamed-options.d.ts +11 -0
  109. package/dist/cli/renamed-options.js +18 -0
  110. package/dist/cli/telemetry.d.ts +2 -2
  111. package/dist/cli/telemetry.js +1 -1
  112. package/dist/comms/capture-surface.d.ts +1 -1
  113. package/dist/comms/catch-host.d.ts +1 -1
  114. package/dist/comms/connections.js +4 -4
  115. package/dist/comms/external-evidence.d.ts +27 -0
  116. package/dist/comms/external-evidence.js +93 -0
  117. package/dist/comms/lease-store.js +7 -7
  118. package/dist/comms/types.js +1 -1
  119. package/dist/evidence/browser-hygiene.d.ts +1 -1
  120. package/dist/evidence/browser-hygiene.js +1 -1
  121. package/dist/evidence/redaction.js +1 -1
  122. package/dist/evidence/secret-scrub.d.ts +9 -0
  123. package/dist/evidence/secret-scrub.js +96 -0
  124. package/dist/feedback/draft.js +7 -9
  125. package/dist/feedback/export-bundle.js +4 -4
  126. package/dist/feedback/export.js +9 -9
  127. package/dist/feedback/feedback.d.ts +1 -1
  128. package/dist/index.d.ts +3 -6
  129. package/dist/index.js +3 -6
  130. package/dist/keys/key-resolution.d.ts +3 -1
  131. package/dist/keys/key-resolution.js +18 -16
  132. package/dist/lab/adapter-extension.d.ts +28 -6
  133. package/dist/lab/adapter-extension.js +65 -126
  134. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  135. package/dist/lab/adapter-scorer-loader.js +24 -0
  136. package/dist/lab/composition-rules.d.ts +2 -0
  137. package/dist/lab/composition-rules.js +35 -26
  138. package/dist/lab/config.js +28 -26
  139. package/dist/lab/device-presets.d.ts +2 -2
  140. package/dist/lab/discover.js +1 -3
  141. package/dist/lab/doctor.d.ts +44 -9
  142. package/dist/lab/doctor.js +149 -41
  143. package/dist/lab/init-plan.js +1 -3
  144. package/dist/lab/keys.js +1 -1
  145. package/dist/lab/lab-deps.d.ts +85 -0
  146. package/dist/lab/lab-deps.js +4 -0
  147. package/dist/lab/parse/actors.js +8 -7
  148. package/dist/lab/parse/comms.js +3 -2
  149. package/dist/lab/parse/execution.js +3 -2
  150. package/dist/lab/parse/subject-state.js +2 -1
  151. package/dist/lab/parse/subject.js +2 -1
  152. package/dist/lab/parse/values.d.ts +0 -1
  153. package/dist/lab/parse/values.js +0 -3
  154. package/dist/lab/persona-resolve.d.ts +3 -3
  155. package/dist/lab/persona-resolve.js +4 -4
  156. package/dist/lab/persona.js +1 -3
  157. package/dist/lab/plan-base.d.ts +6 -2
  158. package/dist/lab/plan-base.js +22 -7
  159. package/dist/lab/plan-participants.d.ts +5 -5
  160. package/dist/lab/plan-participants.js +2 -2
  161. package/dist/lab/plan-types.d.ts +33 -7
  162. package/dist/lab/plan.d.ts +3 -11
  163. package/dist/lab/plan.js +18 -42
  164. package/dist/lab/preflight-result.js +0 -2
  165. package/dist/lab/preflight.d.ts +0 -3
  166. package/dist/lab/preflight.js +1 -1
  167. package/dist/lab/requirements.d.ts +20 -0
  168. package/dist/lab/requirements.js +54 -0
  169. package/dist/lab/route-inputs.d.ts +23 -12
  170. package/dist/lab/route-inputs.js +48 -51
  171. package/dist/lab/routing.d.ts +19 -24
  172. package/dist/lab/routing.js +14 -47
  173. package/dist/lab/run-lab-events.d.ts +6 -11
  174. package/dist/lab/run-lab-events.js +3 -11
  175. package/dist/lab/run-lab-homes.d.ts +64 -0
  176. package/dist/lab/run-lab-homes.js +3 -0
  177. package/dist/lab/run-lab-options.d.ts +12 -66
  178. package/dist/lab/run-lab-options.js +45 -275
  179. package/dist/lab/summary.d.ts +9 -4
  180. package/dist/lab/summary.js +15 -8
  181. package/dist/lab/types.d.ts +132 -132
  182. package/dist/lab/validation.d.ts +15 -15
  183. package/dist/lab/validation.js +28 -28
  184. package/dist/lab/warnings.js +20 -19
  185. package/dist/observer/artifact.d.ts +1 -1
  186. package/dist/observer/artifact.js +3 -3
  187. package/dist/observer/data.js +2 -2
  188. package/dist/observer/render.js +2 -2
  189. package/dist/observer/run-routes.d.ts +1 -1
  190. package/dist/observer/run-routes.js +5 -5
  191. package/dist/observer/serve.d.ts +17 -0
  192. package/dist/observer/serve.js +34 -3
  193. package/dist/observer-app.html +1 -1
  194. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  195. package/dist/routes/computer-use/bundle-parts.js +10 -3
  196. package/dist/routes/computer-use/bundle.d.ts +4 -11
  197. package/dist/routes/computer-use/bundle.js +9 -15
  198. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  199. package/dist/routes/computer-use/diagnostics.js +1 -1
  200. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  201. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  202. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  203. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  204. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  205. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  206. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  207. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  208. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  209. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  210. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  211. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  212. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  213. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  214. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  215. package/dist/routes/computer-use/external-comms.js +19 -43
  216. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  217. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  218. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  219. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  220. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  221. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  222. package/dist/routes/computer-use/live-flush.js +19 -27
  223. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
  224. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  225. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  226. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  227. package/dist/routes/computer-use/local-vm.js +39 -66
  228. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  229. package/dist/routes/computer-use/participant-desktop.js +5 -25
  230. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  231. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  232. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  233. package/dist/routes/computer-use/participant-facts.js +12 -1
  234. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  235. package/dist/routes/computer-use/participant-model.js +58 -33
  236. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  237. package/dist/routes/computer-use/participant-prompt.js +4 -4
  238. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  239. package/dist/routes/computer-use/participant-runs.js +8 -8
  240. package/dist/routes/computer-use/plan.d.ts +21 -29
  241. package/dist/routes/computer-use/plan.js +59 -65
  242. package/dist/routes/computer-use/preflight.d.ts +6 -11
  243. package/dist/routes/computer-use/preflight.js +26 -18
  244. package/dist/routes/computer-use/rerun-selection.js +10 -6
  245. package/dist/routes/computer-use/result.d.ts +1 -1
  246. package/dist/routes/computer-use/result.js +40 -30
  247. package/dist/routes/computer-use/route.d.ts +3 -4
  248. package/dist/routes/computer-use/route.js +21 -19
  249. package/dist/routes/computer-use/self-report.d.ts +2 -2
  250. package/dist/routes/computer-use/self-report.js +4 -4
  251. package/dist/routes/computer-use/setup.d.ts +8 -17
  252. package/dist/routes/computer-use/setup.js +98 -86
  253. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  254. package/dist/routes/computer-use/single-bundle.js +20 -25
  255. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  256. package/dist/routes/computer-use/subject-projection.js +20 -19
  257. package/dist/routes/computer-use/types.d.ts +169 -211
  258. package/dist/routes/computer-use/types.js +13 -6
  259. package/dist/routes/preview.js +0 -1
  260. package/dist/routes/scripted/bundle.d.ts +3 -6
  261. package/dist/routes/scripted/bundle.js +11 -16
  262. package/dist/routes/scripted/plan.d.ts +5 -7
  263. package/dist/routes/scripted/plan.js +6 -4
  264. package/dist/routes/scripted/result.d.ts +4 -1
  265. package/dist/routes/scripted/result.js +10 -6
  266. package/dist/routes/scripted/route.js +10 -11
  267. package/dist/routes/scripted/scenario.d.ts +1 -1
  268. package/dist/routes/scripted/scenario.js +1 -1
  269. package/dist/routes/scripted/setup.d.ts +3 -2
  270. package/dist/routes/scripted/setup.js +22 -21
  271. package/dist/routes/scripted/subject.d.ts +8 -3
  272. package/dist/routes/scripted/subject.js +11 -6
  273. package/dist/routes/scripted/surface-records.js +1 -1
  274. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  275. package/dist/routes/scripted/surface-sessions.js +4 -4
  276. package/dist/routes/scripted/types.d.ts +19 -36
  277. package/dist/routes/scripted/types.js +1 -2
  278. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  279. package/dist/routes/shared-world/bundle.d.ts +2 -2
  280. package/dist/routes/shared-world/bundle.js +22 -26
  281. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  282. package/dist/routes/shared-world/checkpoints.js +4 -4
  283. package/dist/routes/shared-world/comms.d.ts +5 -4
  284. package/dist/routes/shared-world/comms.js +28 -41
  285. package/dist/routes/shared-world/external-public.d.ts +5 -5
  286. package/dist/routes/shared-world/external-public.js +19 -20
  287. package/dist/routes/shared-world/handoff.d.ts +4 -4
  288. package/dist/routes/shared-world/handoff.js +50 -50
  289. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  290. package/dist/routes/shared-world/lobby-code.js +13 -13
  291. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  292. package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
  293. package/dist/routes/shared-world/plan.d.ts +2 -6
  294. package/dist/routes/shared-world/plan.js +1 -2
  295. package/dist/routes/shared-world/provenance.d.ts +4 -4
  296. package/dist/routes/shared-world/provenance.js +4 -4
  297. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  298. package/dist/routes/shared-world/provisioned.js +48 -41
  299. package/dist/routes/shared-world/result.js +31 -19
  300. package/dist/routes/shared-world/route.js +37 -41
  301. package/dist/routes/shared-world/setup.d.ts +5 -4
  302. package/dist/routes/shared-world/setup.js +12 -14
  303. package/dist/routes/shared-world/types.d.ts +53 -126
  304. package/dist/routes/shared-world/types.js +2 -2
  305. package/dist/routes/terminal/adapter.d.ts +8 -8
  306. package/dist/routes/terminal/adapter.js +28 -125
  307. package/dist/routes/terminal/bundle.d.ts +7 -12
  308. package/dist/routes/terminal/bundle.js +24 -34
  309. package/dist/routes/terminal/credentials.d.ts +2 -2
  310. package/dist/routes/terminal/credentials.js +16 -16
  311. package/dist/routes/terminal/dry-run.d.ts +1 -1
  312. package/dist/routes/terminal/dry-run.js +9 -11
  313. package/dist/routes/terminal/encoding.d.ts +1 -1
  314. package/dist/routes/terminal/encoding.js +2 -2
  315. package/dist/routes/terminal/ledger.d.ts +6 -6
  316. package/dist/routes/terminal/ledger.js +9 -9
  317. package/dist/routes/terminal/live-finish.d.ts +1 -2
  318. package/dist/routes/terminal/live-finish.js +21 -20
  319. package/dist/routes/terminal/live-sandbox.d.ts +4 -2
  320. package/dist/routes/terminal/live-sandbox.js +25 -21
  321. package/dist/routes/terminal/participant-text.d.ts +23 -0
  322. package/dist/routes/terminal/participant-text.js +165 -0
  323. package/dist/routes/terminal/plan.d.ts +2 -6
  324. package/dist/routes/terminal/plan.js +13 -9
  325. package/dist/routes/terminal/recorder.d.ts +6 -1
  326. package/dist/routes/terminal/recorder.js +12 -4
  327. package/dist/routes/terminal/result.js +4 -4
  328. package/dist/routes/terminal/route.js +26 -26
  329. package/dist/routes/terminal/runtime.d.ts +3 -2
  330. package/dist/routes/terminal/runtime.js +3 -3
  331. package/dist/routes/terminal/sandbox.d.ts +5 -3
  332. package/dist/routes/terminal/sandbox.js +13 -16
  333. package/dist/routes/terminal/session.js +16 -14
  334. package/dist/routes/terminal/token-usage.js +5 -5
  335. package/dist/routes/terminal/trace.d.ts +5 -8
  336. package/dist/routes/terminal/trace.js +9 -64
  337. package/dist/routes/terminal/types.d.ts +85 -93
  338. package/dist/routes/terminal/types.js +9 -4
  339. package/dist/run/active-runs.d.ts +13 -0
  340. package/dist/run/active-runs.js +12 -0
  341. package/dist/run/bundle-shape.d.ts +2 -1
  342. package/dist/run/bundle-shape.js +4 -4
  343. package/dist/run/bundle.d.ts +63 -56
  344. package/dist/run/bundle.js +9 -8
  345. package/dist/run/cost-summary.js +3 -2
  346. package/dist/run/costs.d.ts +6 -6
  347. package/dist/run/costs.js +10 -10
  348. package/dist/run/detail.d.ts +5 -5
  349. package/dist/run/detail.js +6 -6
  350. package/dist/run/dry-run.js +5 -12
  351. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  352. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  353. package/dist/run/feedback-shape.js +1 -1
  354. package/dist/run/judge.d.ts +16 -4
  355. package/dist/run/judge.js +24 -7
  356. package/dist/run/locate.d.ts +2 -0
  357. package/dist/run/locate.js +3 -1
  358. package/dist/run/outcomes.d.ts +3 -3
  359. package/dist/run/outcomes.js +3 -3
  360. package/dist/run/participant-records.d.ts +2 -2
  361. package/dist/run/participant-records.js +2 -2
  362. package/dist/run/paths.js +1 -1
  363. package/dist/run/pricing.d.ts +19 -9
  364. package/dist/run/pricing.js +30 -18
  365. package/dist/run/projection.d.ts +13 -13
  366. package/dist/run/projection.js +8 -8
  367. package/dist/run/reclaim.d.ts +7 -1
  368. package/dist/run/reclaim.js +24 -4
  369. package/dist/run/results.d.ts +1 -1
  370. package/dist/run/run-index.d.ts +1 -1
  371. package/dist/run/run-index.js +11 -11
  372. package/dist/run/run.d.ts +4 -2
  373. package/dist/run/run.js +9 -5
  374. package/dist/run/sandbox-receipts.d.ts +4 -4
  375. package/dist/run/sandbox-receipts.js +4 -4
  376. package/dist/run/shared-world-evidence.d.ts +47 -47
  377. package/dist/run/shared-world-shape.d.ts +3 -3
  378. package/dist/run/shared-world-shape.js +11 -11
  379. package/dist/run/stats.d.ts +5 -5
  380. package/dist/run/stats.js +8 -8
  381. package/dist/run/status.d.ts +16 -6
  382. package/dist/run/status.js +31 -8
  383. package/dist/run/streams.d.ts +26 -19
  384. package/dist/run/terminal-contract.d.ts +5 -5
  385. package/dist/run/terminal-contract.js +4 -4
  386. package/dist/run/transient-comms-secrets.d.ts +5 -0
  387. package/dist/run/transient-comms-secrets.js +12 -0
  388. package/dist/run-lab.d.ts +36 -34
  389. package/dist/run-lab.js +41 -37
  390. package/dist/subject/desktop-cli.d.ts +1 -1
  391. package/dist/subject/desktop-cli.js +1 -1
  392. package/dist/subject/local-tree-archive.d.ts +1 -1
  393. package/dist/subject/local-tree-archive.js +4 -4
  394. package/dist/subject/local-tree.d.ts +2 -2
  395. package/dist/subject/local-tree.js +1 -1
  396. package/dist/subject/node-bootstrap.d.ts +1 -1
  397. package/dist/subject/node-bootstrap.js +4 -4
  398. package/dist/subject/runtime.js +5 -5
  399. package/dist/subject/serve.js +1 -1
  400. package/dist/subject/steps.d.ts +4 -4
  401. package/dist/subject/steps.js +5 -5
  402. package/dist/substrates/desktop-session.d.ts +2 -0
  403. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  404. package/dist/substrates/e2b/cdp-probe.js +1 -1
  405. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  406. package/dist/substrates/e2b/desktop-browser.js +4 -4
  407. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  408. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  409. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  410. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  411. package/dist/substrates/e2b/desktop-media.js +2 -2
  412. package/dist/substrates/e2b/sandbox.d.ts +2 -0
  413. package/dist/substrates/e2b/sandbox.js +22 -8
  414. package/dist/substrates/e2b/sdk.d.ts +12 -1
  415. package/dist/substrates/e2b/sdk.js +30 -9
  416. package/dist/substrates/local/runtime-host.d.ts +2 -0
  417. package/dist/substrates/local/runtime-host.js +6 -0
  418. package/dist/tui/actions.d.ts +7 -5
  419. package/dist/tui/actions.js +18 -9
  420. package/dist/tui-app.js +42 -42
  421. package/dist/verify/actor.d.ts +10 -10
  422. package/dist/verify/actor.js +15 -15
  423. package/dist/verify/artifacts.d.ts +1 -1
  424. package/dist/verify/artifacts.js +3 -3
  425. package/dist/verify/costs.d.ts +2 -2
  426. package/dist/verify/costs.js +2 -2
  427. package/dist/verify/liveness.d.ts +1 -1
  428. package/dist/verify/liveness.js +4 -1
  429. package/dist/verify/rerun.d.ts +1 -1
  430. package/dist/verify/rerun.js +1 -1
  431. package/dist/verify/shared-world.js +2 -2
  432. package/dist/verify/verify.js +6 -6
  433. package/docs/README.md +1 -1
  434. package/docs/architecture/actor-contract.md +60 -22
  435. package/docs/architecture/desktop-sessions.md +9 -9
  436. package/docs/architecture/external-public-shared-world.md +5 -0
  437. package/docs/architecture/observer.md +4 -4
  438. package/docs/architecture/restricted-codex-analysis.md +40 -4
  439. package/docs/architecture/state-driven-executor.md +4 -5
  440. package/docs/architecture/task-protocol-support.md +3 -5
  441. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  442. package/docs/contracts/run-bundle.md +10 -8
  443. package/docs/contracts/schemas.md +109 -53
  444. package/docs/contracts/study-analysis.md +24 -0
  445. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  446. package/docs/product/automatic-analysis.md +1 -0
  447. package/docs/ramp/README.md +2 -1
  448. package/package.json +4 -4
  449. package/skills/humanish/SKILL.md +3 -2
  450. package/skills/humanish/agents/openai.yaml +1 -1
  451. package/dist/deprecated.d.ts +0 -90
  452. package/dist/deprecated.js +0 -106
  453. package/dist/lab/bag-overrides.d.ts +0 -18
  454. package/dist/lab/bag-overrides.js +0 -121
  455. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  456. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  457. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  458. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  459. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -1,5 +1,5 @@
1
- // The first half of an E2B desktop lane's preparation: acquire the sandbox, verify its screen, and
2
- // provision the subject. Each step fills the lane's state; a step that cannot proceed throws.
1
+ // The first half of an E2B desktop participant's preparation: acquire the sandbox, verify its screen, and
2
+ // provision the subject. Each step fills the participant's state; a step that cannot proceed throws.
3
3
  import { redactText } from "../../../evidence/redaction.js";
4
4
  import { provisionCloneSubject } from "../../../subject/clone.js";
5
5
  import { provisionDesktopCli } from "../../../subject/desktop-cli.js";
@@ -10,22 +10,24 @@ import { acquireE2BDesktopSandbox, e2bDesktopTemplate } from "../../../substrate
10
10
  import { loadE2BDesktopModule } from "../../../substrates/e2b/sdk.js";
11
11
  import { e2bShell } from "../../../substrates/e2b/shell.js";
12
12
  import { attachReceivingInbox, participantCommsEnv, startCommsCatch } from "./comms.js";
13
+ import { participantSubjectEnv } from "../types.js";
13
14
  export const CUA_ACTOR_LAB_PROVIDER_METADATA = {
14
15
  mode: "cua-actor-lab",
15
16
  tool: "humanish",
16
17
  };
17
18
  /**
18
- * Create the lane's sandbox, record its resources, run the adopter's prepare hook, and attach the
19
- * lane's inbox and comms catch. Returns the sandbox, which the later steps drive.
19
+ * Create the participant's sandbox, record its resources, run the adopter's prepare hook, and attach the
20
+ * participant's inbox and comms catch. Returns the sandbox, which the later steps drive.
20
21
  */
21
22
  export async function acquireParticipantDesktop(ctx, state) {
22
23
  const { spec, deps, warnings } = ctx;
23
- const { config, subjectEnvNames, env } = deps;
24
- const subjectEnvValues = config.subject.envValues ?? {};
24
+ const { residual, env } = deps;
25
+ const subjectEnvNames = participantSubjectEnv(deps.subject);
26
+ const subjectEnvValues = residual.subject.envValues ?? {};
25
27
  // Off-app comms (#297): the base-URL env is injected at sandbox create, so the app reads it at
26
28
  // boot; the catch starts right after create.
27
29
  const commsEnv = participantCommsEnv(ctx.comms);
28
- const desktopModule = await (deps.hooks.loadDesktopModule ?? loadE2BDesktopModule)();
30
+ const desktopModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
29
31
  // An explicit template wins. Speech gets the versioned media image; ordinary
30
32
  // browser studies retain the SDK default desktop.
31
33
  const acquired = await acquireE2BDesktopSandbox({
@@ -36,7 +38,7 @@ export async function acquireParticipantDesktop(ctx, state) {
36
38
  timeoutMs: deps.sandboxMs,
37
39
  metadata: {
38
40
  ...CUA_ACTOR_LAB_PROVIDER_METADATA,
39
- labId: config.id,
41
+ labId: deps.labId,
40
42
  simId: spec.recordId,
41
43
  laneId: spec.planned.id,
42
44
  laneIndex: String(spec.planned.index),
@@ -62,7 +64,7 @@ export async function acquireParticipantDesktop(ctx, state) {
62
64
  dpi: 96,
63
65
  lifecycle: { onTimeout: "kill" },
64
66
  },
65
- template: e2bDesktopTemplate(config),
67
+ template: e2bDesktopTemplate(residual),
66
68
  retry: {
67
69
  // The default loader reclaims an acquired handle before retrying failed desktop startup.
68
70
  // Its error names the cleanup outcome; pre-construction allocation failures remain unowned.
@@ -76,7 +78,7 @@ export async function acquireParticipantDesktop(ctx, state) {
76
78
  });
77
79
  },
78
80
  },
79
- // The receipt is on disk before any work, so `humanish reclaim` can kill this lane's
81
+ // The receipt is on disk before any work, so `humanish reclaim` can kill this participant's
80
82
  // sandbox by exact id after an interrupt.
81
83
  receipt: { root: deps.artifactRoot, participantId: spec.planned.id, now: deps.now },
82
84
  });
@@ -92,13 +94,10 @@ export async function acquireParticipantDesktop(ctx, state) {
92
94
  if ("reason" in desktopResources) {
93
95
  warnings.push(`Desktop resource size unavailable (${desktopResources.reason}); compute cost remains unpriced.`);
94
96
  }
95
- if (deps.hooks.prepareDesktop) {
96
- await deps.hooks.prepareDesktop(desktop, {
97
- laneId: spec.planned.id,
98
- laneIndex: spec.planned.index,
99
- laneCount: deps.participantCount,
100
- });
101
- }
97
+ await deps.prepareDesktop?.(desktop, {
98
+ kind: "participant",
99
+ participant: { id: spec.planned.id, index: spec.planned.index, count: deps.participantCount },
100
+ });
102
101
  if (deps.receiving) {
103
102
  state.receivingInboxUrl = await attachReceivingInbox(shell, spec, { ...deps, receiving: deps.receiving }, ctx.targetUrl);
104
103
  state.commsArtifactPath = "comms/receiving.json";
@@ -108,7 +107,7 @@ export async function acquireParticipantDesktop(ctx, state) {
108
107
  return desktop;
109
108
  }
110
109
  /**
111
- * Verify the lane's screen in the sandbox. A mismatch fails the lane closed unless the run records
110
+ * Verify the participant's screen in the sandbox. A mismatch fails the participant closed unless the run records
112
111
  * requested and verified geometry side by side.
113
112
  */
114
113
  export async function verifyParticipantScreen(ctx, state, desktop) {
@@ -135,7 +134,7 @@ export async function verifyParticipantScreen(ctx, state, desktop) {
135
134
  }
136
135
  if (screenGeometry.error && screenGeometry.verified) {
137
136
  // record-evidence policy: the bundle keeps requested vs verified as separate facts and
138
- // discloses the divergence instead of failing this lane's world mid-flight.
137
+ // discloses the divergence instead of failing this participant's world mid-flight.
139
138
  const mismatchWarning = deps.scrubKnownValues(`Participant ${spec.planned.id} requested a ${spec.planned.device.resolution[0]}x${spec.planned.device.resolution[1]} screen but xdpyinfo reports ${screenGeometry.verified.width}x${screenGeometry.verified.height}; recording requested vs verified separately instead of failing the participant closed.`);
140
139
  warnings.push(mismatchWarning);
141
140
  state.desktopGeometry = {
@@ -147,28 +146,26 @@ export async function verifyParticipantScreen(ctx, state, desktop) {
147
146
  /** Install a desktop CLI, or clone or unpack the subject and serve it, in the sandbox. */
148
147
  export async function provisionParticipantSubject(ctx, state, desktop) {
149
148
  const { deps } = ctx;
150
- const { config, cloneRoute, localTreeRoute, serve, subjectRepo } = deps;
149
+ const { residual, subject } = deps;
151
150
  const shell = e2bShell(desktop);
152
- if (ctx.desktopCliRoute) {
151
+ if (subject.kind === "desktop-cli") {
153
152
  // Prepare the runtime and any declared product install, UNKEYED. With install omitted,
154
153
  // the participant discovers and installs the product from its public surfaces.
155
154
  await provisionDesktopCli(shell, {
156
- product: config.subject.product?.name ?? "",
157
- ...(config.subject.product?.install === undefined
158
- ? {}
159
- : { install: config.subject.product.install }),
155
+ product: subject.product.name,
156
+ ...(subject.product.install === undefined ? {} : { install: subject.product.install }),
160
157
  requestTimeoutMs: deps.requestTimeoutMs,
161
158
  scrub: deps.scrubKnownValues,
162
159
  onPhase: ctx.onSubjectPhase,
163
160
  });
164
161
  }
165
- if (cloneRoute && serve && subjectRepo) {
162
+ if (subject.kind === "clone") {
166
163
  state.subjectCommit = await provisionCloneSubject(shell, {
167
- repo: subjectRepo,
168
- depth: config.subject.clone?.depth ?? 1,
169
- serve,
170
- ...(config.subject.state === undefined ? {} : { state: config.subject.state }),
171
- hasGithubToken: deps.hasGithubToken,
164
+ repo: subject.repo,
165
+ depth: residual.subject.clone?.depth ?? 1,
166
+ serve: subject.serve,
167
+ ...(subject.state === undefined ? {} : { state: subject.state }),
168
+ hasGithubToken: subject.env.includes("GITHUB_TOKEN"),
172
169
  requestTimeoutMs: deps.requestTimeoutMs,
173
170
  scrub: deps.scrubKnownValues,
174
171
  onCommit: (commit) => {
@@ -178,21 +175,21 @@ export async function provisionParticipantSubject(ctx, state, desktop) {
178
175
  state.stateStepRecords.push(record);
179
176
  },
180
177
  onPhase: ctx.onSubjectPhase,
181
- ...deps.hooks.detachedTimers,
178
+ ...deps.detachedTimers,
182
179
  });
183
180
  }
184
- else if (localTreeRoute && serve && deps.localTreeArchiveBuffer) {
181
+ else if (subject.kind === "local-tree" && deps.localTreeArchiveBuffer) {
185
182
  await provisionLocalTreeSubject(shell, {
186
183
  archiveBuffer: deps.localTreeArchiveBuffer,
187
- serve,
188
- ...(config.subject.state === undefined ? {} : { state: config.subject.state }),
184
+ serve: subject.serve,
185
+ ...(subject.state === undefined ? {} : { state: subject.state }),
189
186
  requestTimeoutMs: deps.requestTimeoutMs,
190
187
  scrub: deps.scrubKnownValues,
191
188
  onStateStep: (record) => {
192
189
  state.stateStepRecords.push(record);
193
190
  },
194
191
  onPhase: ctx.onSubjectPhase,
195
- ...deps.hooks.detachedTimers,
192
+ ...deps.detachedTimers,
196
193
  });
197
194
  }
198
195
  }
@@ -9,6 +9,6 @@ export declare function startParticipantMedia(ctx: E2BParticipantContext, state:
9
9
  export declare function openParticipantSurface(ctx: E2BParticipantContext, state: E2BParticipantState, desktop: E2BDesktopSandbox): Promise<void>;
10
10
  /**
11
11
  * Measure the browser window and start the live stream. A stream that cannot start is a warning;
12
- * unusable browser geometry fails the lane before any participant action.
12
+ * unusable browser geometry fails the participant before any action.
13
13
  */
14
14
  export declare function startParticipantStream(ctx: E2BParticipantContext, state: E2BParticipantState, desktop: E2BDesktopSandbox): Promise<void>;
@@ -1,6 +1,6 @@
1
- // The second half of an E2B desktop lane's preparation, and the start of its session: speech and
1
+ // The second half of an E2B desktop participant's preparation, and the start of its session: speech and
2
2
  // recording, then the browser or terminal the participant sees, then the live stream. Each step
3
- // fills the lane's state.
3
+ // fills the participant's state.
4
4
  import { redactText, toErrorMessage } from "../../../evidence/redaction.js";
5
5
  import { CHROME_DEVTOOLS_PORT, DESKTOP_SETTLE_MS, openDesktopBrowserTarget, openDesktopTerminal, startDesktopStream, } from "../../../substrates/e2b/desktop-browser.js";
6
6
  import { captureDesktopBrowserGeometry } from "../../../substrates/e2b/desktop-geometry.js";
@@ -10,7 +10,7 @@ import { applyParticipantMobileFidelity, mobileLaunchFlags } from "./fidelity.js
10
10
  /** Start the declared speech worker and screen recording. A recording that cannot start is a warning. */
11
11
  export async function startParticipantMedia(ctx, state, desktop) {
12
12
  const { spec, deps, warnings } = ctx;
13
- const requestedMedia = deps.config.execution?.desktop?.media;
13
+ const requestedMedia = deps.residual.execution?.desktop?.media;
14
14
  if (!ctx.desktopCliRoute && requestedMedia?.microphone?.source === "speech") {
15
15
  state.speech = await startE2BDesktopMedia({
16
16
  desktop,
@@ -20,7 +20,7 @@ export async function startParticipantMedia(ctx, state, desktop) {
20
20
  requestTimeoutMs: deps.requestTimeoutMs,
21
21
  });
22
22
  }
23
- const requestedRecording = deps.config.execution?.desktop?.recording;
23
+ const requestedRecording = deps.residual.execution?.desktop?.recording;
24
24
  if (requestedRecording) {
25
25
  try {
26
26
  state.recording = await startE2BDesktopRecording({
@@ -43,28 +43,28 @@ export async function startParticipantMedia(ctx, state, desktop) {
43
43
  */
44
44
  export async function openParticipantSurface(ctx, state, desktop) {
45
45
  const { spec, deps, warnings, targetUrl } = ctx;
46
- const { config } = deps;
47
- if (ctx.desktopCliRoute) {
46
+ const { residual, subject } = deps;
47
+ if (subject.kind === "desktop-cli") {
48
48
  // A terminal window, opened the way the browser is opened on every other route: the
49
49
  // participant arrives at a desktop with the thing they were asked to use already in front
50
50
  // of them. They can still open another from the dock — that is the point of a desktop.
51
- await openDesktopTerminal(desktop, deps.requestTimeoutMs, config.subject.product?.workdir);
51
+ await openDesktopTerminal(desktop, deps.requestTimeoutMs, subject.product.workdir);
52
52
  await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
53
53
  return;
54
54
  }
55
- const requestedMedia = config.execution?.desktop?.media;
55
+ const requestedMedia = residual.execution?.desktop?.media;
56
56
  // A declared camera (#509) is in place before the browser starts: the feed is generated or
57
- // uploaded first, and a feed that cannot be produced fails the lane closed here.
57
+ // uploaded first, and a feed that cannot be produced fails the participant closed here.
58
58
  const mediaEvidence = requestedMedia === undefined
59
59
  ? undefined
60
- : await prepareDesktopMedia(desktop, requestedMedia, config.policies?.mediaPermission ?? "prompt", deps.labCwd, deps.requestTimeoutMs);
61
- const emulationFlags = mobileLaunchFlags(config, spec);
62
- const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs, config.execution?.desktop?.browser, [...emulationFlags, ...(mediaEvidence?.flags ?? [])], state.speech?.env ?? state.recording?.env);
60
+ : await prepareDesktopMedia(desktop, requestedMedia, residual.policies?.mediaPermission ?? "prompt", deps.labCwd, deps.requestTimeoutMs);
61
+ const emulationFlags = mobileLaunchFlags(residual, spec);
62
+ const browserLaunch = await openDesktopBrowserTarget(desktop, targetUrl, deps.requestTimeoutMs, residual.execution?.desktop?.browser, [...emulationFlags, ...(mediaEvidence?.flags ?? [])], state.speech?.env ?? state.recording?.env);
63
63
  state.desktopBrowser =
64
64
  mediaEvidence === undefined
65
65
  ? browserLaunch.evidence
66
66
  : {
67
- requested: config.execution?.desktop?.browser ?? "default",
67
+ requested: residual.execution?.desktop?.browser ?? "default",
68
68
  ...browserLaunch.evidence,
69
69
  media: mediaEvidence,
70
70
  };
@@ -77,7 +77,7 @@ export async function openParticipantSurface(ctx, state, desktop) {
77
77
  noteDevToolsReadiness(ctx, browserLaunch.devTools, emulationFlags.length > 0);
78
78
  await desktop.wait(DESKTOP_SETTLE_MS).catch(() => undefined);
79
79
  // Mobile fidelity (#221) is applied outside startParticipantStream's best-effort catch, so a request
80
- // that cannot be applied fails the lane closed.
80
+ // that cannot be applied fails the participant closed.
81
81
  state.fidelity = await applyParticipantMobileFidelity({
82
82
  desktop,
83
83
  spec,
@@ -90,14 +90,14 @@ export async function openParticipantSurface(ctx, state, desktop) {
90
90
  });
91
91
  }
92
92
  /**
93
- * DevTools answering later than this after launch is recorded as a warning on the lane. Six live
93
+ * DevTools answering later than this after launch is recorded as a warning on the participant. Six live
94
94
  * launches answered in 4.8-7.7 s; the reads this wait now guards used to give up at about 11 s.
95
95
  */
96
96
  const SLOW_DEVTOOLS_MS = 10_000;
97
97
  /**
98
98
  * Records how Chrome's DevTools port answered after launch, as a timed phase in the bundle. A
99
- * device-emulated lane fails closed when the port never answered, because emulation is applied
100
- * over DevTools. Other lanes continue with a warning: their DevTools reads already degrade to
99
+ * device-emulated participant fails closed when the port never answered, because emulation is applied
100
+ * over DevTools. Other participants continue with a warning: their DevTools reads already degrade to
101
101
  * warnings of their own.
102
102
  */
103
103
  function noteDevToolsReadiness(ctx, devTools, emulated) {
@@ -132,7 +132,7 @@ function noteDevToolsReadiness(ctx, devTools, emulated) {
132
132
  }
133
133
  /**
134
134
  * Measure the browser window and start the live stream. A stream that cannot start is a warning;
135
- * unusable browser geometry fails the lane before any participant action.
135
+ * unusable browser geometry fails the participant before any action.
136
136
  */
137
137
  export async function startParticipantStream(ctx, state, desktop) {
138
138
  const { spec, deps, warnings } = ctx;
@@ -156,8 +156,8 @@ export async function startParticipantStream(ctx, state, desktop) {
156
156
  state.browserWindowId = browserGeometry.browserWindowId;
157
157
  state.browserTargetId = browserGeometry.browserTargetId;
158
158
  }
159
- // A browser lane streams its browser window when one was found. A CLI lane has no window id
160
- // and streams the whole desktop: a person studying a terminal app opens other windows, and
159
+ // A browser participant streams its browser window when one was found. A CLI participant has
160
+ // no window id and streams the whole desktop: a person studying a terminal app opens other windows, and
161
161
  // a stream bound to the first one would quietly stop being evidence.
162
162
  await startDesktopStream(desktop, state.browserWindowId);
163
163
  const candidateStreamUrl = desktop.stream.getUrl({
@@ -168,8 +168,9 @@ export async function startParticipantStream(ctx, state, desktop) {
168
168
  });
169
169
  if (typeof candidateStreamUrl === "string" && candidateStreamUrl.trim().length > 0) {
170
170
  state.streamUrl = candidateStreamUrl;
171
- await deps.hooks.onRuntimeStreamReady?.({
172
- laneId: spec.planned.id,
171
+ await deps.onStream({
172
+ type: "ready",
173
+ participantId: spec.planned.id,
173
174
  sandboxId: desktop.sandboxId,
174
175
  simId: spec.recordId,
175
176
  streamId: spec.streamId,
@@ -184,7 +185,7 @@ export async function startParticipantStream(ctx, state, desktop) {
184
185
  warnings.push(`Live desktop stream unavailable (run continues; evidence still captured): ${redactText(deps.scrubKnownValues(toErrorMessage(error)))}`);
185
186
  }
186
187
  // This is outside the stream's best-effort catch: unusable geometry is a harness failure,
187
- // never a participant finding about missing controls. Both per-lane and shared-world seats
188
+ // never a participant finding about missing controls. Both computer-use and shared-world participants
188
189
  // use this route.
189
190
  if (state.initialBrowserGeometry?.unusable !== undefined) {
190
191
  state.failureCode = "HUMANISH_CUA_LAB_DEVICE_GEOMETRY";
@@ -12,11 +12,11 @@ import type { E2BDesktopSandbox } from "../../../substrates/e2b/sdk.js";
12
12
  import type { ParticipantDesktopEvidence } from "../participant-desktop.js";
13
13
  import type { ParticipantComms, RunningCommsCatch } from "./comms.js";
14
14
  import type { ParticipantFidelity } from "./fidelity.js";
15
- import type { CuaActorLabErrorCode, CuaParticipantDeps, DesktopParticipantRun } from "../types.js";
16
- /** What every step of one lane reads: its spec, the run's dependencies and where it points. */
15
+ import type { CuaActorLabErrorCode, E2BDesktopDeps, DesktopParticipantRun, SandboxReleaseFact } from "../types.js";
16
+ /** What every step of one participant reads: its spec, the run's dependencies and where it points. */
17
17
  export interface E2BParticipantContext {
18
18
  readonly spec: DesktopParticipantRun;
19
- readonly deps: CuaParticipantDeps;
19
+ readonly deps: E2BDesktopDeps;
20
20
  readonly warnings: string[];
21
21
  readonly targetUrl: string;
22
22
  readonly desktopCliRoute: boolean;
@@ -37,6 +37,7 @@ export interface E2BParticipantState {
37
37
  sandboxTornDownAtMs: number | undefined;
38
38
  desktopResources: DesktopResourceObservation | undefined;
39
39
  released: boolean;
40
+ sandboxRelease: SandboxReleaseFact | undefined;
40
41
  failureCode: CuaActorLabErrorCode | undefined;
41
42
  commsCatch: RunningCommsCatch | undefined;
42
43
  commsArtifactPath: string | undefined;
@@ -61,5 +62,5 @@ export interface E2BParticipantState {
61
62
  streamUrl: string | undefined;
62
63
  }
63
64
  export declare function newParticipantState(spec: DesktopParticipantRun): E2BParticipantState;
64
- /** The lane's outcome evidence, read from its state. */
65
+ /** The participant's outcome evidence, read from its state. */
65
66
  export declare function desktopEvidenceOf(state: E2BParticipantState): ParticipantDesktopEvidence;
@@ -1,5 +1,5 @@
1
- // What one E2B desktop lane records as it runs. The prepare, start and teardown steps fill one
2
- // record in order, and desktopEvidenceOf reads it for the lane's outcome.
1
+ // What one E2B desktop participant records as it runs. The prepare, start and teardown steps fill one
2
+ // record in order, and desktopEvidenceOf reads it for the participant's outcome.
3
3
  import { declaredScreenForRender, } from "../../../substrates/e2b/desktop-geometry.js";
4
4
  export function newParticipantState(spec) {
5
5
  const declaredScreen = declaredScreenForRender(spec.planned.device.preset, spec.planned.device.name, spec.planned.device.resolution);
@@ -11,6 +11,7 @@ export function newParticipantState(spec) {
11
11
  sandboxTornDownAtMs: undefined,
12
12
  desktopResources: undefined,
13
13
  released: false,
14
+ sandboxRelease: undefined,
14
15
  failureCode: undefined,
15
16
  commsCatch: undefined,
16
17
  commsArtifactPath: undefined,
@@ -42,7 +43,7 @@ export function newParticipantState(spec) {
42
43
  streamUrl: undefined,
43
44
  };
44
45
  }
45
- /** The lane's outcome evidence, read from its state. */
46
+ /** The participant's outcome evidence, read from its state. */
46
47
  export function desktopEvidenceOf(state) {
47
48
  // Host-side approximation of the E2B desktop's billed lifetime; feeds the desktop-minute cost
48
49
  // estimate. Never negative.
@@ -54,6 +55,7 @@ export function desktopEvidenceOf(state) {
54
55
  ...(desktopDurationMs === undefined ? {} : { desktopDurationMs }),
55
56
  ...(state.desktopResources === undefined ? {} : { desktopResources: state.desktopResources }),
56
57
  released: state.released,
58
+ ...(state.sandboxRelease === undefined ? {} : { sandboxRelease: state.sandboxRelease }),
57
59
  streamUrlPresent: state.streamUrl !== undefined,
58
60
  ...(state.subjectCommit === undefined ? {} : { subjectCommit: state.subjectCommit }),
59
61
  ...(state.desktopBrowser === undefined ? {} : { desktopBrowser: state.desktopBrowser }),
@@ -1,6 +1,6 @@
1
1
  import type { E2BParticipantContext, E2BParticipantState } from "./state.js";
2
2
  /**
3
- * Finish a lane: collect its final geometry and comms evidence, then stop its media and release
3
+ * Finish a participant: collect its final geometry and comms evidence, then stop its media and release
4
4
  * its sandbox. Evidence failures are warnings; the release always runs.
5
5
  */
6
6
  export declare function finishE2BDesktop(ctx: E2BParticipantContext, state: E2BParticipantState, failed: boolean): Promise<void>;
@@ -1,4 +1,4 @@
1
- // Teardown for one E2B desktop lane: its final geometry and comms evidence are collected, then the
1
+ // Teardown for one E2B desktop participant: its final geometry and comms evidence are collected, then the
2
2
  // recording and speech worker, then the sandbox is released by id (or kept for debugging), with a
3
3
  // warning for every outcome that is not a confirmed release.
4
4
  import { collectDesktopRecording } from "../../../evidence/desktop-recording-artifact.js";
@@ -8,14 +8,14 @@ import { e2bShell } from "../../../substrates/e2b/shell.js";
8
8
  import { drainCommsEvidence } from "./comms.js";
9
9
  import { finalParticipantGeometry } from "./fidelity.js";
10
10
  /**
11
- * Each route's own keep flag gates its own lane only: a clone.keep can never leak into a local-tree
12
- * lane's teardown decision, and vice versa.
11
+ * Each route's own keep flag gates its own participants only: a clone.keep can never leak into a
12
+ * local-tree participant's teardown decision, and vice versa.
13
13
  */
14
14
  function participantKeepReason(deps) {
15
- const { config, cloneRoute, localTreeRoute } = deps;
16
- if (cloneRoute && config.subject.clone?.keep === true)
15
+ const { residual, subject } = deps;
16
+ if (subject.kind === "clone" && residual.subject.clone?.keep === true)
17
17
  return "subject.clone.keep";
18
- if (localTreeRoute && config.subject.localTree?.keep === true)
18
+ if (subject.kind === "local-tree" && residual.subject.localTree?.keep === true)
19
19
  return "subject.localTree.keep";
20
20
  return undefined;
21
21
  }
@@ -38,17 +38,18 @@ async function stopParticipantMedia(args) {
38
38
  return evidence;
39
39
  }
40
40
  /**
41
- * Release the lane's sandbox, or keep it when a keep flag is set and the lane failed. Returns true
42
- * only when the release is confirmed. A kept or unconfirmed sandbox can still accrue compute cost,
43
- * which the warnings say.
41
+ * Release the participant's sandbox, or keep it when a keep flag is set and the participant failed. `released`
42
+ * is true only when the release is confirmed; otherwise `sandboxRelease` says why. A kept or
43
+ * unconfirmed sandbox can still accrue compute cost, which the warnings say.
44
44
  */
45
45
  async function releaseParticipantDesktop(args) {
46
46
  const { allocation, keepReason, deps, warnings } = args;
47
47
  const keepForDebug = keepReason !== undefined && args.failed;
48
48
  const released = await allocation.close({ retainForDebug: keepForDebug });
49
49
  if (released.status === "retained") {
50
- warnings.push(`Sandbox ${allocation.resourceId} kept for debugging (${keepReason} on failure); reclaim it via E2B or it will be killed on its server-side timeout.`);
51
- return false;
50
+ const warning = `Sandbox ${allocation.resourceId} kept for debugging (${keepReason} on failure); reclaim it via E2B or it will be killed on its server-side timeout.`;
51
+ warnings.push(warning);
52
+ return { released: false, sandboxRelease: { state: "retained", warning } };
52
53
  }
53
54
  const reading = readE2BRelease(released, {
54
55
  label: "Sandbox",
@@ -57,10 +58,18 @@ async function releaseParticipantDesktop(args) {
57
58
  });
58
59
  if (reading.warning)
59
60
  warnings.push(reading.warning);
60
- return reading.released;
61
+ if (reading.released)
62
+ return { released: true };
63
+ return {
64
+ released: false,
65
+ sandboxRelease: {
66
+ state: "unconfirmed",
67
+ warning: reading.warning ?? "Sandbox release is unconfirmed.",
68
+ },
69
+ };
61
70
  }
62
71
  /**
63
- * Finish a lane: collect its final geometry and comms evidence, then stop its media and release
72
+ * Finish a participant: collect its final geometry and comms evidence, then stop its media and release
64
73
  * its sandbox. Evidence failures are warnings; the release always runs.
65
74
  */
66
75
  export async function finishE2BDesktop(ctx, state, failed) {
@@ -122,24 +131,27 @@ export async function finishE2BDesktop(ctx, state, failed) {
122
131
  mediaStop: state.mediaStop,
123
132
  warnings,
124
133
  });
125
- state.released = await releaseParticipantDesktop({
134
+ const release = await releaseParticipantDesktop({
126
135
  allocation,
127
136
  keepReason: participantKeepReason(deps),
128
137
  failed,
129
138
  deps,
130
139
  warnings,
131
140
  });
141
+ state.released = release.released;
142
+ state.sandboxRelease = release.sandboxRelease;
132
143
  // Close the observed span. A kept or unconfirmed sandbox can still accrue compute cost; the
133
144
  // summary records that remaining lifetime as unknown instead of calling this complete.
134
145
  state.sandboxTornDownAtMs = deps.now();
135
- // The lane's live stream is now a dead page whichever teardown path ran (released, kept, or
146
+ // The participant's live stream is now a dead page whichever teardown path ran (released, kept, or
136
147
  // release-failed-awaiting-TTL); tell the watch overlay so the tile falls back to recorded
137
148
  // evidence instead of "sandbox not found" (#357). Guarded: a viewer callback must never
138
149
  // break teardown.
139
150
  if (state.streamUrl !== undefined) {
140
151
  try {
141
- await deps.hooks.onRuntimeStreamEnded?.({
142
- laneId: spec.planned.id,
152
+ await deps.onStream({
153
+ type: "ended",
154
+ participantId: spec.planned.id,
143
155
  simId: spec.recordId,
144
156
  streamId: spec.streamId,
145
157
  });
@@ -2,12 +2,12 @@ import type { LabCommsEmail, LabCommsExternal } from "../../lab/types.js";
2
2
  import type { PreparedRunArtifactPaths } from "../../run/paths.js";
3
3
  import type { DesktopParticipantRun, ParticipantRunOutcome } from "./types.js";
4
4
  /**
5
- * Adopter-hosted drain (#380): once per RUN, after every lane finished — the catch is one
5
+ * Adopter-hosted drain (#380): once per RUN, after every participant finished — the catch is one
6
6
  * shared external endpoint, not a per-sandbox file. Same routing and digest-only artifact as
7
- * the in-sandbox drain; the artifact is registered on every lane that declared a recipient
7
+ * the in-sandbox drain; the artifact is registered on every participant that declared a recipient
8
8
  * address, since the thread carries each inbox's mail. A drain failure never fails the run.
9
9
  *
10
- * Returns the warnings the drain produced; lanes that received mail get `commsArtifactPath`.
10
+ * Returns the warnings the drain produced; participants that received mail get `commsArtifactPath`.
11
11
  */
12
12
  export declare function drainExternalComms(args: {
13
13
  externalCommsConfig: LabCommsExternal;
@@ -16,5 +16,5 @@ export declare function drainExternalComms(args: {
16
16
  runPaths: PreparedRunArtifactPaths;
17
17
  participantRuns: readonly DesktopParticipantRun[];
18
18
  outcomes: ParticipantRunOutcome[];
19
- scrubKnownValues: (text: string) => string;
19
+ knownSecretValues: readonly string[];
20
20
  }): Promise<string[]>;
@@ -1,55 +1,31 @@
1
- import { FakeInbox } from "../../comms/fake-inbox.js";
2
- import { collectExternalCommsThread } from "../../comms/sandbox-catch.js";
3
- import { redactText, toErrorMessage } from "../../evidence/redaction.js";
4
- import { writeContainedOutputFile } from "../../run/contained-output.js";
1
+ import { collectExternalCommsEvidence } from "../../comms/external-evidence.js";
5
2
  import { participantHasInboxRecipient } from "./participant-desktop.js";
6
- import { addressedRecipients } from "../../lab/parse/comms.js";
7
3
  /**
8
- * Adopter-hosted drain (#380): once per RUN, after every lane finished — the catch is one
4
+ * Adopter-hosted drain (#380): once per RUN, after every participant finished — the catch is one
9
5
  * shared external endpoint, not a per-sandbox file. Same routing and digest-only artifact as
10
- * the in-sandbox drain; the artifact is registered on every lane that declared a recipient
6
+ * the in-sandbox drain; the artifact is registered on every participant that declared a recipient
11
7
  * address, since the thread carries each inbox's mail. A drain failure never fails the run.
12
8
  *
13
- * Returns the warnings the drain produced; lanes that received mail get `commsArtifactPath`.
9
+ * Returns the warnings the drain produced; participants that received mail get `commsArtifactPath`.
14
10
  */
15
11
  export async function drainExternalComms(args) {
16
- const { externalCommsConfig, externalCommsEmail, env, runPaths, participantRuns, outcomes, scrubKnownValues, } = args;
17
- const warnings = [];
18
- try {
19
- const commsChannel = new FakeInbox();
20
- const commsInboxes = [];
21
- for (const recipient of addressedRecipients(externalCommsEmail)) {
22
- commsInboxes.push(await commsChannel.provisionAddress(recipient.participantId, recipient.address));
23
- }
24
- const authToken = externalCommsConfig.authTokenEnv === undefined
25
- ? undefined
26
- : env[externalCommsConfig.authTokenEnv];
27
- const collected = await collectExternalCommsThread({
28
- external: { ...externalCommsConfig, ...(authToken === undefined ? {} : { authToken }) },
29
- channel: commsChannel,
30
- inboxes: commsInboxes,
31
- });
32
- if (collected.artifact) {
33
- const commsPath = "comms/thread.json";
34
- await writeContainedOutputFile(runPaths, commsPath, `${JSON.stringify(collected.artifact, null, 2)}\n`, "utf8");
35
- for (const [index, outcome] of outcomes.entries()) {
36
- const participantId = participantRuns[index]?.planned.id;
37
- if (participantId !== undefined &&
38
- outcome.commsArtifactPath === undefined &&
39
- participantHasInboxRecipient(externalCommsEmail, participantId)) {
40
- outcome.commsArtifactPath = commsPath;
41
- }
12
+ const { externalCommsEmail, participantRuns, outcomes } = args;
13
+ const { path: commsPath, warnings } = await collectExternalCommsEvidence({
14
+ external: args.externalCommsConfig,
15
+ email: externalCommsEmail,
16
+ env: args.env,
17
+ runPaths: args.runPaths,
18
+ knownSecretValues: args.knownSecretValues,
19
+ });
20
+ if (commsPath !== undefined) {
21
+ for (const [index, outcome] of outcomes.entries()) {
22
+ const participantId = participantRuns[index]?.planned.id;
23
+ if (participantId !== undefined &&
24
+ outcome.commsArtifactPath === undefined &&
25
+ participantHasInboxRecipient(externalCommsEmail, participantId)) {
26
+ outcome.commsArtifactPath = commsPath;
42
27
  }
43
28
  }
44
- else if (collected.captured > 0) {
45
- warnings.push(`Comms catch captured ${collected.captured} email send(s) but none matched a declared recipient inbox — no comms evidence written. Declare comms.email.recipients[].address to match the address the app sends to.`);
46
- }
47
- else {
48
- warnings.push(`Comms catch captured ZERO email sends — your app never delivered mail through the catch at ${externalCommsConfig.catchBaseUrl}. Verify the app's email-API base URL points at it and that the flow reached an email step.`);
49
- }
50
- }
51
- catch (error) {
52
- warnings.push(`Comms evidence collection failed against the adopter-hosted catch (run continues): ${redactText(scrubKnownValues(toErrorMessage(error)))}`);
53
29
  }
54
30
  return warnings;
55
31
  }
@@ -1,10 +1,10 @@
1
1
  import { type RunBundle } from "../../run/bundle.js";
2
2
  import type { CuaFanoutBundleArgs } from "./types.js";
3
3
  /**
4
- * Project N>1 fan-out lanes into a humanish.run-bundle.v1 (the evidence schema is unchanged; this
5
- * is a new producer for the multi-stream shape). One sim + one stream per lane; per-lane
4
+ * Project N>1 fan-out participants into a humanish.run-bundle.v1 (the evidence schema is unchanged; this
5
+ * is a new producer for the multi-stream shape). One sim + one stream per participant; per-participant
6
6
  * provenance/session events; a recorded `cua-lab.fanout.plan` event (and a `cua-lab.fanout.fail-fast`
7
- * event when a harness error skipped queued lanes). N-ary verify/Observer already handle multiple
7
+ * event when a harness error skipped queued participants). N-ary verify/Observer already handle multiple
8
8
  * streams. A single-participant run without a rerun never reaches here: buildCuaRunBundle
9
9
  * (bundle.ts) sends it to buildSingleParticipantBundle (single-bundle.ts).
10
10
  */