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
@@ -3,27 +3,27 @@ import { receivingPublication } from "../../comms/receiving-runtime.js";
3
3
  import { actorEnding } from "../../actors/stop-cause.js";
4
4
  import { redactText } from "../../evidence/redaction.js";
5
5
  import { REVIEW_SCHEMA, bundleArtifacts, bundleHead, } from "../../run/bundle.js";
6
- import { aggregateTaskFunnels, formatParticipantOutcomes, formatStudyTaskFunnel, tallyParticipantOutcomes, withCuaReviewProvenance, } from "../../run/outcomes.js";
6
+ import { aggregateTaskFunnels, formatParticipantOutcomes, formatRunTaskFunnel, tallyParticipantOutcomes, withCuaReviewProvenance, } from "../../run/outcomes.js";
7
7
  import { participantFeedbackCandidates, providerResourcesForOutcome } from "./bundle-parts.js";
8
8
  import { participantFactsOf } from "./participant-facts.js";
9
9
  import { participantPassed, participantStatus } from "../../run/judge.js";
10
10
  import { buildRunCostSummary, desktopSpanToMinutes } from "../../run/cost-summary.js";
11
11
  import { formatParticipantPlanEntry } from "./participant-runs.js";
12
- import { fanoutParticipantRecords } from "./fanout-lanes.js";
12
+ import { fanoutParticipantRecords } from "./fanout-records.js";
13
13
  /** The run's first two events: its creation and the fan-out plan. */
14
14
  function fanoutPlanEvents(args) {
15
15
  const { specs, plan } = args;
16
16
  const events = [];
17
17
  events.push({
18
18
  id: "event-000-created",
19
- at: args.createdAt,
19
+ at: args.run.createdAt,
20
20
  level: "info",
21
21
  type: "cua-lab.run.created",
22
22
  message: `Created computer-use fan-out run for ${plan.labId} (actor ${args.descriptor.id}, ${specs.length} participants, one world each).`,
23
23
  });
24
24
  events.push({
25
25
  id: "event-001-fanout-plan",
26
- at: args.createdAt,
26
+ at: args.run.createdAt,
27
27
  level: "info",
28
28
  type: "cua-lab.fanout.plan",
29
29
  message: `Fan-out plan: ${args.participantPlan.laneCount} participant(s) (${args.participantPlan.strategy}), concurrency ${args.participantPlan.concurrency}, ${args.participantPlan.waves} wave(s); session budget ${Math.round(args.participantPlan.perLaneSessionBudgetMs / 1000)}s per participant; worst-case ~${args.participantPlan.worstCaseSandboxMinutes} sandbox-minutes${args.dryRun ? " (dry-run: $0)" : ""}. Participants: ${args.participantPlan.lanes.map(formatParticipantPlanEntry).join(", ")}.`,
@@ -32,7 +32,7 @@ function fanoutPlanEvents(args) {
32
32
  }
33
33
  function fanoutReview(args, streams) {
34
34
  const { specs, outcomes } = args;
35
- // The judge's verdict: live fan-out must prove every lane (judgeParticipants).
35
+ // The judge's verdict: live fan-out must prove every participant (judgeParticipants).
36
36
  const verdict = args.verdict;
37
37
  const passedParticipants = (outcomes ?? []).filter((outcome) => participantPassed(participantFactsOf(outcome))).length;
38
38
  // What happened to the PARTICIPANTS, with the denominator attached. The verdict above has to
@@ -40,10 +40,10 @@ function fanoutReview(args, streams) {
40
40
  const terminalOutcomes = (outcomes ?? []).filter((outcome) => outcome?.session?.status !== undefined);
41
41
  const participants = terminalOutcomes.length > 0
42
42
  ? tallyParticipantOutcomes(
43
- // A NO-ENGAGEMENT lane is not a participant who reached the goal. It said "done" having
43
+ // A NO-ENGAGEMENT participant is not one who reached the goal. It said "done" having
44
44
  // taken zero actions and said nothing, and `passedParticipants` above already refuses to
45
45
  // count it — but `reachedGoal` was reading the trace status directly, so one run could be both
46
- // "not a passed lane" AND "1/1 reached the goal". The headline number a researcher reads
46
+ // "not a passed participant" AND "1/1 reached the goal". The headline number a researcher reads
47
47
  // first was the dishonest one. Found by a provider bug that ended a study on turn one.
48
48
  terminalOutcomes.map((outcome) => participantStatus(outcome.session.status, {
49
49
  noEngagement: outcome.noEngagement === true,
@@ -58,7 +58,7 @@ function fanoutReview(args, streams) {
58
58
  const participantFunnels = (outcomes ?? [])
59
59
  .map((outcome) => outcome?.session?.trace.taskFunnel)
60
60
  .filter((funnel) => funnel !== undefined);
61
- const studyTasks = args.inProgress === true ? undefined : aggregateTaskFunnels(participantFunnels);
61
+ const runTasks = args.inProgress === true ? undefined : aggregateTaskFunnels(participantFunnels);
62
62
  const participantEndings = terminalOutcomes.map((outcome) => {
63
63
  const ending = actorEnding(outcome.session.trace);
64
64
  return {
@@ -70,12 +70,12 @@ function fanoutReview(args, streams) {
70
70
  schema: REVIEW_SCHEMA,
71
71
  verdict,
72
72
  ...(participants === undefined ? {} : { participants }),
73
- ...(studyTasks === undefined ? {} : { tasks: studyTasks }),
73
+ ...(runTasks === undefined ? {} : { tasks: runTasks }),
74
74
  summary: args.inProgress === true
75
75
  ? `Live computer-use fan-out is running (${specs.length} participants, one world each); terminal participant evidence has not been written yet.`
76
76
  : args.dryRun
77
77
  ? `${args.rerun ? `Rerun contract from ${args.rerun.sourceRunId}: ` : ""}Dry-run fan-out contract: ${specs.length} participants composed for ${args.descriptor.id} against ${args.appUrl}, one world each; no desktops launched, $0 spend.`
78
- : `${args.rerun ? `Rerun from ${args.rerun.sourceRunId}: ` : ""}Computer-use fan-out (${specs.length} participants, one world each): ${passedParticipants}/${specs.length} participant(s) reached a terminal, engaged verdict${participants ? `: ${formatParticipantOutcomes(participants, participantEndings)}` : ""}${studyTasks ? `; tasks: ${formatStudyTaskFunnel(studyTasks)}` : ""}.`,
78
+ : `${args.rerun ? `Rerun from ${args.rerun.sourceRunId}: ` : ""}Computer-use fan-out (${specs.length} participants, one world each): ${passedParticipants}/${specs.length} participant(s) reached a terminal, engaged verdict${participants ? `: ${formatParticipantOutcomes(participants, participantEndings)}` : ""}${runTasks ? `; tasks: ${formatRunTaskFunnel(runTasks)}` : ""}.`,
79
79
  gaps: args.inProgress === true
80
80
  ? ["Live fan-out session is still running."]
81
81
  : args.dryRun
@@ -93,7 +93,7 @@ function fanoutReview(args, streams) {
93
93
  }, streams);
94
94
  return review;
95
95
  }
96
- /** The configured browser and, when every lane resolved the same one, that browser. */
96
+ /** The configured browser and, when every participant resolved the same one, that browser. */
97
97
  function fanoutDesktopBrowser(args) {
98
98
  const { outcomes, plan } = args;
99
99
  const configuredBrowser = plan.residual.execution?.desktop?.browser;
@@ -112,9 +112,9 @@ function fanoutDesktopBrowser(args) {
112
112
  }
113
113
  function fanoutCost(args) {
114
114
  const { specs, outcomes } = args;
115
- // Run-level cost ESTIMATE: one model-token line per lane that ran a session (from its persisted
115
+ // Run-level cost ESTIMATE: one model-token line per participant that ran a session (from its persisted
116
116
  // trace.estimatedCost) + a desktop line per owned allocation, priced at its observed resources.
117
- // Per-lane worlds have no shared provisioning to double-count. Omitted on a pure dry-run.
117
+ // `per-lane-worlds` participants have no shared provisioning to double-count. Omitted on a pure dry-run.
118
118
  const costTraces = specs
119
119
  .map((spec, index) => ({ participantId: spec.planned.id, outcome: outcomes?.[index] }))
120
120
  .filter((entry) => entry.outcome?.session !== undefined)
@@ -135,7 +135,7 @@ function fanoutFeedbackCandidates(args) {
135
135
  return args.dryRun || args.inProgress === true
136
136
  ? []
137
137
  : participantFeedbackCandidates({
138
- runId: args.runId,
138
+ runId: args.run.runId,
139
139
  scenarioId: `cua-${plan.labId}`,
140
140
  adapterId: plan.labId,
141
141
  goal: redactText(specs[0].evidenceInstructions ?? specs[0].instructions),
@@ -159,10 +159,10 @@ function fanoutFeedbackCandidates(args) {
159
159
  });
160
160
  }
161
161
  /**
162
- * Project N>1 fan-out lanes into a humanish.run-bundle.v1 (the evidence schema is unchanged; this
163
- * is a new producer for the multi-stream shape). One sim + one stream per lane; per-lane
162
+ * Project N>1 fan-out participants into a humanish.run-bundle.v1 (the evidence schema is unchanged; this
163
+ * is a new producer for the multi-stream shape). One sim + one stream per participant; per-participant
164
164
  * provenance/session events; a recorded `cua-lab.fanout.plan` event (and a `cua-lab.fanout.fail-fast`
165
- * event when a harness error skipped queued lanes). N-ary verify/Observer already handle multiple
165
+ * event when a harness error skipped queued participants). N-ary verify/Observer already handle multiple
166
166
  * streams. A single-participant run without a rerun never reaches here: buildCuaRunBundle
167
167
  * (bundle.ts) sends it to buildSingleParticipantBundle (single-bundle.ts).
168
168
  */
@@ -176,7 +176,7 @@ export function buildCuaFanoutBundle(args) {
176
176
  if (args.rerun) {
177
177
  events.push({
178
178
  id: nextEventId("fanout-rerun"),
179
- at: args.createdAt,
179
+ at: args.run.createdAt,
180
180
  level: "info",
181
181
  type: "cua-lab.fanout.rerun",
182
182
  message: `Rerun selected ${args.rerun.selectedLaneIds.length} participant(s) from ${args.rerun.sourceRunId}: ${args.rerun.previous.map((prior) => `${prior.laneId} was ${prior.status}${prior.completionReason ? `/${prior.completionReason}` : ""}`).join(", ")}. This is a new linked run; the source run verdict is unchanged.`,
@@ -191,7 +191,7 @@ export function buildCuaFanoutBundle(args) {
191
191
  if (args.failFastReason) {
192
192
  events.push({
193
193
  id: nextEventId("fanout-fail-fast"),
194
- at: args.createdAt,
194
+ at: args.run.createdAt,
195
195
  level: "warn",
196
196
  type: "cua-lab.fanout.fail-fast",
197
197
  message: `Fan-out fail-fast: ${args.failFastReason}. In-flight participants finished; queued participants were skipped (blocked); completed evidence is retained.`,
@@ -204,19 +204,15 @@ export function buildCuaFanoutBundle(args) {
204
204
  const desktopBrowser = fanoutDesktopBrowser(args);
205
205
  const providerResources = (outcomes ?? []).flatMap((outcome) => providerResourcesForOutcome({
206
206
  outcome,
207
- createdAt: args.createdAt,
207
+ createdAt: args.run.createdAt,
208
208
  ids: outcome.spec,
209
209
  participantId: outcome.spec.planned.id,
210
210
  }));
211
211
  const cost = fanoutCost(args);
212
212
  return {
213
- ...bundleHead({
213
+ ...bundleHead(args.run, {
214
214
  ...receivingPublication(args.plan.residual, args.dryRun),
215
- runId: args.runId,
216
- mode: args.dryRun ? "dry-run" : "live",
217
215
  participants: specs.length,
218
- createdAt: args.createdAt,
219
- ...(args.lab === undefined ? {} : { lab: args.lab }),
220
216
  source: args.source,
221
217
  }),
222
218
  persona: {
@@ -228,9 +224,9 @@ export function buildCuaFanoutBundle(args) {
228
224
  scenario: {
229
225
  id: `cua-${plan.labId}`,
230
226
  title: plan.title ?? `Computer-use fan-out: ${plan.labId}`,
231
- // Redacted at WRITE time, like every other raw-text surface in the bundle. Lane records are
232
- // digest-only by design, but scenario.goal keeps one lane's composed instructions verbatim —
233
- // and an adopter whose authored lane text must name a runtime world URL (an inbox on a route
227
+ // Redacted at WRITE time, like every other raw-text surface in the bundle. Participant records are
228
+ // digest-only by design, but scenario.goal keeps one participant's composed instructions verbatim —
229
+ // and an adopter whose authored participant text must name a runtime world URL (an inbox on a route
234
230
  // where the harness does not inject one) put an *.e2b.app address in it. That landed raw here
235
231
  // and in observer-data.json, the sensitive-text scanner matched it, and verify failed a bundle
236
232
  // this writer produced. The only adopter-side workaround was scanner evasion (#412).
@@ -242,7 +238,7 @@ export function buildCuaFanoutBundle(args) {
242
238
  },
243
239
  lifecycle: [
244
240
  {
245
- at: args.createdAt,
241
+ at: args.run.createdAt,
246
242
  event: "cua-lab.run.created",
247
243
  message: `Created computer-use fan-out run with ${specs.length} participants, each in its own desktop browser (actor ${args.descriptor.id}).`,
248
244
  },
@@ -4,6 +4,10 @@ import { participantAssignment } from "../../lab/participant-assignment.js";
4
4
  import { participantEvent, participantRecord, participantStream, } from "../../run/participant-records.js";
5
5
  import { declaredScreenForRender } from "../../substrates/e2b/desktop-geometry.js";
6
6
  import { describeSubjectState, phaseEventIdSuffix, publicSafeAppUrlLabel } from "./bundle-parts.js";
7
+ import { judgedStatus } from "../../run/judge.js";
8
+ import { participantFactsOf } from "./participant-facts.js";
9
+ import { participantSubjectEnv } from "./types.js";
10
+ const describeEnvNames = (names) => names.length > 0 ? names.join(", ") : "none";
7
11
  function fanoutParticipantView(args, spec, index) {
8
12
  const { outcomes, plan } = args;
9
13
  const outcome = outcomes?.[index];
@@ -77,14 +81,15 @@ function fanoutParticipantRecord(args, spec, index, view) {
77
81
  : outcome?.sessionError !== undefined
78
82
  ? `Participant ${spec.planned.id} failed before a terminal session verdict: ${outcome.sessionError}`
79
83
  : `Contract participant ${spec.planned.id} (${spec.persona.id}/${spec.planned.device.name}) for ${args.descriptor.id} against ${publicTargetUrl}.`,
80
- startedAt: args.createdAt,
81
- updatedAt: args.createdAt,
84
+ startedAt: args.run.createdAt,
85
+ updatedAt: args.run.createdAt,
82
86
  });
83
87
  }
84
88
  function fanoutParticipantStream(args, spec, view) {
85
89
  const { plan } = args;
86
90
  const { outcome, publicTargetUrl, session, desktopGeometry, screenshots } = view;
87
91
  const { lastScreenshot, status, reason, screenshotMode } = view;
92
+ const judged = outcome === undefined ? undefined : judgedStatus(participantFactsOf(outcome));
88
93
  return participantStream(spec, {
89
94
  ...(spec.evidenceAssignment === undefined
90
95
  ? {}
@@ -101,8 +106,9 @@ function fanoutParticipantStream(args, spec, view) {
101
106
  kind: "browser",
102
107
  label: `CUA participant ${spec.planned.id}: ${plan.labId}`,
103
108
  status,
109
+ ...(judged === undefined ? {} : { judgedStatus: judged }),
104
110
  transport: "snapshot",
105
- updatedAt: args.createdAt,
111
+ updatedAt: args.run.createdAt,
106
112
  embed: lastScreenshot
107
113
  ? {
108
114
  kind: "screenshot",
@@ -174,11 +180,11 @@ function fanoutSubjectEvents(ctx, spec, view) {
174
180
  const { publicTargetUrl, subject, session } = view;
175
181
  const events = [];
176
182
  const record = (event) => events.push(participantEvent(spec, event));
177
- // Per-lane subject provenance (invariant 5).
178
- if (args.cloneRoute && args.publicRepo) {
183
+ // Per-participant subject provenance (invariant 5).
184
+ if (args.plan.runner.subject.kind === "clone" && args.publicRepo) {
179
185
  record({
180
186
  id: nextEventId(`subject-${spec.planned.id}`),
181
- at: args.createdAt,
187
+ at: args.run.createdAt,
182
188
  level: "info",
183
189
  type: "cua-lab.subject.provenance",
184
190
  message: `Participant ${spec.planned.id}: ${args.dryRun
@@ -187,13 +193,13 @@ function fanoutSubjectEvents(ctx, spec, view) {
187
193
  ? session
188
194
  ? `subject cloned from ${args.publicRepo}@${subject.commit} and served at ${publicTargetUrl} in-sandbox`
189
195
  : `subject cloned from ${args.publicRepo}@${subject.commit}; serving did not complete (see session error)`
190
- : `subject clone attempted from ${args.publicRepo}; commit unresolved`} (subject env names: ${args.subjectEnvNames.length > 0 ? args.subjectEnvNames.join(", ") : "none"}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
196
+ : `subject clone attempted from ${args.publicRepo}; commit unresolved`} (subject env names: ${describeEnvNames(participantSubjectEnv(args.plan.runner.subject))}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
191
197
  });
192
198
  }
193
199
  else if (subject.source === "local-tree") {
194
200
  record({
195
201
  id: nextEventId(`subject-${spec.planned.id}`),
196
- at: args.createdAt,
202
+ at: args.run.createdAt,
197
203
  level: "info",
198
204
  type: "cua-lab.subject.provenance",
199
205
  message: `Participant ${spec.planned.id}: ${args.dryRun
@@ -202,13 +208,13 @@ function fanoutSubjectEvents(ctx, spec, view) {
202
208
  ? session
203
209
  ? `subject packed (archiveSha256 ${subject.archiveSha256}${subject.dirty === true ? ", dirty working tree" : subject.dirty === false ? ", clean working tree" : ""}) and served at ${publicTargetUrl} in-sandbox`
204
210
  : `subject packed (archiveSha256 ${subject.archiveSha256}); serving did not complete (see session error)`
205
- : "subject local-tree packing attempted; archive digest unresolved"} (subject env names: ${args.subjectEnvNames.length > 0 ? args.subjectEnvNames.join(", ") : "none"}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
211
+ : "subject local-tree packing attempted; archive digest unresolved"} (subject env names: ${describeEnvNames(participantSubjectEnv(args.plan.runner.subject))}; values never persisted); state: ${describeSubjectState(subject.state, args.dryRun)}.`,
206
212
  });
207
213
  }
208
214
  else {
209
215
  record({
210
216
  id: nextEventId(`subject-${spec.planned.id}`),
211
- at: args.createdAt,
217
+ at: args.run.createdAt,
212
218
  level: "info",
213
219
  type: "cua-lab.subject.declared",
214
220
  message: `Participant ${spec.planned.id}: subject app declared at ${publicTargetUrl} (loopback inside the participant's own desktop sandbox).`,
@@ -221,11 +227,11 @@ function fanoutOutcomeEvents(ctx, spec, view) {
221
227
  const { outcome, session, desktopGeometry } = view;
222
228
  const events = [];
223
229
  const record = (event) => events.push(participantEvent(spec, event));
224
- // Per-lane session event.
230
+ // Per-participant session event.
225
231
  if (session) {
226
232
  record({
227
233
  id: nextEventId(`session-${spec.planned.id}`),
228
- at: args.createdAt,
234
+ at: args.run.createdAt,
229
235
  level: session.status === "passed" ? "info" : "warn",
230
236
  type: `cua-lab.session.${session.completionReason}`,
231
237
  message: `Participant ${spec.planned.id} ${session.status}: ${session.reason}`,
@@ -234,7 +240,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
234
240
  else if (args.inProgress === true && outcome === undefined) {
235
241
  record({
236
242
  id: nextEventId(`running-${spec.planned.id}`),
237
- at: args.createdAt,
243
+ at: args.run.createdAt,
238
244
  level: "info",
239
245
  type: "cua-lab.session.running",
240
246
  message: `Participant ${spec.planned.id}: live computer-use session is running; terminal evidence has not been written yet.`,
@@ -243,7 +249,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
243
249
  else if (outcome?.skippedReason !== undefined) {
244
250
  record({
245
251
  id: nextEventId(`blocked-${spec.planned.id}`),
246
- at: args.createdAt,
252
+ at: args.run.createdAt,
247
253
  level: "warn",
248
254
  type: "cua-lab.session.blocked",
249
255
  message: `Participant ${spec.planned.id} ${outcome.skippedReason}.`,
@@ -252,7 +258,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
252
258
  else if (outcome?.sessionError !== undefined) {
253
259
  record({
254
260
  id: nextEventId(`session-error-${spec.planned.id}`),
255
- at: args.createdAt,
261
+ at: args.run.createdAt,
256
262
  level: "error",
257
263
  type: "cua-lab.session.error",
258
264
  message: `Participant ${spec.planned.id}: ${outcome.sessionError}`,
@@ -261,7 +267,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
261
267
  else {
262
268
  record({
263
269
  id: nextEventId(`contract-${spec.planned.id}`),
264
- at: args.createdAt,
270
+ at: args.run.createdAt,
265
271
  level: "info",
266
272
  type: "cua-lab.contract.ready",
267
273
  message: `Participant ${spec.planned.id}: dry-run contract participant ready; switch scenario.mode to live for a real desktop session.`,
@@ -270,14 +276,14 @@ function fanoutOutcomeEvents(ctx, spec, view) {
270
276
  for (const warning of desktopGeometry.warnings ?? []) {
271
277
  record({
272
278
  id: nextEventId(`geometry-warning-${spec.planned.id}`),
273
- at: args.createdAt,
279
+ at: args.run.createdAt,
274
280
  level: "warn",
275
281
  type: "cua-lab.geometry.warning",
276
282
  message: warning,
277
283
  });
278
284
  }
279
- // Persisted per-lane phase trail (real boot timing): one RunEvent per COMPLETED phase
280
- // boundary this lane recorded (started events never persist here; they carry no durationMs).
285
+ // Persisted per-participant phase trail (real boot timing): one RunEvent per COMPLETED phase
286
+ // boundary this participant recorded (started events never persist here; they carry no durationMs).
281
287
  for (const phase of outcome?.phaseRecords ?? []) {
282
288
  record({
283
289
  id: nextEventId(`phase-${spec.planned.id}-${phaseEventIdSuffix(phase.type)}`),
@@ -1,14 +1,7 @@
1
- import type { CuaActorDescriptor } from "../../actors/registry.js";
2
- import type { LabConfig } from "../../lab/types.js";
3
1
  import type { ParticipantDesktop } from "./participant-desktop.js";
4
- import type { CuaActorLabHooks } from "./types.js";
5
- /** What an in-process desktop reads: the caller's executor hook and the arguments it receives. */
6
- interface InProcessDesktopDeps {
7
- config: LabConfig;
8
- descriptor: CuaActorDescriptor;
9
- appUrl: string;
10
- hooks: Pick<CuaActorLabHooks, "buildExecutor">;
11
- }
2
+ import type { CuaParticipantDeps } from "./types.js";
3
+ /** What an in-process desktop reads: the caller's executor and the app it drives. */
4
+ type InProcessDesktopDeps = Pick<CuaParticipantDeps, "appUrl" | "inProcessExecutor">;
12
5
  /**
13
6
  * The caller's executor as a participant desktop. prepare acquires nothing; openSession builds the
14
7
  * executor once; finalize is idempotent and has nothing to release; snapshot records no sandbox.
@@ -19,15 +19,9 @@ export function createInProcessDesktop(deps) {
19
19
  if (!preparationStarted || opened || finalization)
20
20
  throw new Error("The participant desktop must be prepared and may only be opened once, before finalization.");
21
21
  opened = true;
22
- const buildExecutor = deps.hooks.buildExecutor;
23
- if (buildExecutor === undefined)
24
- throw new Error("The in-process route needs hooks.buildExecutor.");
25
- const executor = await buildExecutor({
26
- config: deps.config,
27
- actor: deps.descriptor,
28
- appUrl: deps.appUrl,
29
- });
30
- return { executor };
22
+ if (deps.inProcessExecutor === undefined)
23
+ throw new Error("The in-process route needs RunLabOptions.inProcess.");
24
+ return { executor: await deps.inProcessExecutor(deps.appUrl) };
31
25
  },
32
26
  finalize() {
33
27
  return (finalization ??= Promise.resolve());
@@ -2,7 +2,8 @@ import type { ActorTokenUsage, ActorTraceItem } from "../../actors/contract.js";
2
2
  import type { CuaLiveMetadata } from "../../actors/computer-use/loop.js";
3
3
  import { type ObserverResult } from "../../observer/render.js";
4
4
  import type { RunBundle } from "../../run/bundle.js";
5
- import type { CuaActorLabHooks, DesktopParticipantRun } from "./types.js";
5
+ import type { RunLabHomes } from "../../lab/run-lab-homes.js";
6
+ import type { DesktopParticipantRun } from "./types.js";
6
7
  export interface LiveTraceFlush {
7
8
  /** Record a participant's recorded-so-far items; the bundle rewrite follows on the flush
8
9
  * schedule. */
@@ -11,7 +12,7 @@ export interface LiveTraceFlush {
11
12
  stop: () => Promise<void>;
12
13
  }
13
14
  /**
14
- * Incremental live flush (#441): as each lane's loop reports its recorded-so-far items,
15
+ * Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
15
16
  * rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
16
17
  * Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
17
18
  * write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
@@ -27,12 +28,13 @@ export declare function startLiveTraceFlush(args: {
27
28
  write: (bundle: RunBundle) => Promise<void>;
28
29
  }): LiveTraceFlush;
29
30
  /**
30
- * The live desktop views (runtime stream URLs) lanes report, attached to whichever Observer shows
31
+ * The live desktop views (runtime stream URLs) participants report, attached to whichever Observer shows
31
32
  * the run. The URLs carry auth, so they live in memory and on the Observer result, never in run
32
33
  * artifacts.
33
34
  */
34
- export declare function trackRuntimeStreams(hooks: CuaActorLabHooks): {
35
- hooks: CuaActorLabHooks;
35
+ export declare function trackRuntimeStreams(onStream: RunLabHomes["onStream"] | undefined): {
36
+ /** Records each stream for the Observer, after the caller's onStream. */
37
+ onStream: NonNullable<RunLabHomes["onStream"]>;
36
38
  /** From now on, keep this live Observer's stream list current. */
37
39
  showIn: (observer: ObserverResult & {
38
40
  ok: true;
@@ -1,8 +1,7 @@
1
1
  import { attachObserverRuntimeStreamUrls } from "../../observer/render.js";
2
2
  import {} from "../../observer/run-routes.js";
3
- import { HOOK_MEMBERS, withHookOverrides } from "../../lab/bag-overrides.js";
4
3
  /**
5
- * Incremental live flush (#441): as each lane's loop reports its recorded-so-far items,
4
+ * Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
6
5
  * rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
7
6
  * Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
8
7
  * write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
@@ -12,12 +11,12 @@ import { HOOK_MEMBERS, withHookOverrides } from "../../lab/bag-overrides.js";
12
11
  export function startLiveTraceFlush(args) {
13
12
  const { bundle, participantRuns, model, write } = args;
14
13
  const streamIdByParticipant = new Map(participantRuns.map((spec) => [spec.planned.id, spec.streamId]));
15
- // The persona each lane is running, so the live flush can say who is in it.
14
+ // The persona each participant is running, so the live flush can say who is in it.
16
15
  const personaByStream = new Map(participantRuns
17
16
  .map((spec) => [spec.streamId, spec.persona?.id])
18
17
  .filter((entry) => typeof entry[1] === "string"));
19
18
  const liveItemsByStream = new Map();
20
- // Running token usage per lane, so a run in flight can price itself instead of reporting the
19
+ // Running token usage per participant, so a run in flight can price itself instead of reporting the
21
20
  // cost as unknown until the moment it ends.
22
21
  const liveUsageByStream = new Map();
23
22
  const liveMetadataByStream = new Map();
@@ -43,8 +42,8 @@ export function startLiveTraceFlush(args) {
43
42
  liveActor: {
44
43
  schema: "humanish.live-actor.v1",
45
44
  updatedAt,
46
- // WHO is in this lane, carried while the run is live. Without it a surface
47
- // watching a live run can only name the lane, and "CUA browser — observer-live-
45
+ // WHO this participant is, carried while the run is live. Without it a
46
+ // surface watching a live run can only name the participant id, and "CUA browser — observer-live-
48
47
  // check" is the harness talking about itself where the participant should be.
49
48
  ...(personaByStream.get(stream.id) === undefined
50
49
  ? {}
@@ -114,34 +113,27 @@ export function startLiveTraceFlush(args) {
114
113
  return { flush, stop };
115
114
  }
116
115
  /**
117
- * The live desktop views (runtime stream URLs) lanes report, attached to whichever Observer shows
116
+ * The live desktop views (runtime stream URLs) participants report, attached to whichever Observer shows
118
117
  * the run. The URLs carry auth, so they live in memory and on the Observer result, never in run
119
118
  * artifacts.
120
119
  */
121
- export function trackRuntimeStreams(hooks) {
120
+ export function trackRuntimeStreams(onStream) {
122
121
  let liveObserver;
123
122
  const urls = [];
124
123
  return {
125
- // The caller's bag may be a class instance, so it is wrapped rather than spread.
126
- hooks: withHookOverrides(hooks, HOOK_MEMBERS.cua, {
127
- onRuntimeStreamReady: async (stream) => {
128
- await hooks.onRuntimeStreamReady?.(stream);
129
- urls.push({ streamId: stream.streamId, url: stream.url });
130
- if (liveObserver)
131
- attachObserverRuntimeStreamUrls(liveObserver, urls);
132
- },
133
- onRuntimeStreamEnded: async (stream) => {
134
- await hooks.onRuntimeStreamEnded?.(stream);
135
- // Mark, never remove: the tile needs to KNOW the live view ended (and say so) rather than
136
- // have the stream silently vanish from the overlay (#357).
137
- for (const entry of urls) {
138
- if (entry.streamId === stream.streamId)
124
+ onStream: async (event) => {
125
+ await onStream?.(event);
126
+ if (event.type === "ready")
127
+ urls.push({ streamId: event.streamId, url: event.url });
128
+ // Mark, never remove: the tile needs to KNOW the live view ended (and say so) rather than
129
+ // have the stream silently vanish from the overlay (#357).
130
+ else
131
+ for (const entry of urls)
132
+ if (entry.streamId === event.streamId)
139
133
  entry.ended = true;
140
- }
141
- if (liveObserver)
142
- attachObserverRuntimeStreamUrls(liveObserver, urls);
143
- },
144
- }),
134
+ if (liveObserver)
135
+ attachObserverRuntimeStreamUrls(liveObserver, urls);
136
+ },
145
137
  showIn: (observer) => {
146
138
  liveObserver = observer;
147
139
  },
@@ -1,23 +1,24 @@
1
1
  // The computer-use run's live phase: the in-progress bundle and its live-trace flush, email
2
- // receiving, the lanes themselves, and the drain of an operator-hosted inbox.
2
+ // receiving, the participants themselves, and the drain of an operator-hosted inbox.
3
3
  import { prepareReceivingRun } from "../../comms/receiving-runtime.js";
4
4
  import { liveObserverResult } from "../../observer/live.js";
5
- import { DEFAULT_OPENAI_CU_MODEL } from "../../actors/computer-use/openai-provider.js";
6
- import { runAllCuaParticipants } from "./lanes.js";
5
+ import { pricedModel } from "../../lab/plan-base.js";
6
+ import { runAllCuaParticipants } from "./participant-execution.js";
7
7
  import { startLiveTraceFlush } from "./live-flush.js";
8
8
  import { drainExternalComms } from "./external-comms.js";
9
9
  import { buildCuaRunBundle, judgeComputerUseRun } from "./bundle.js";
10
- import {} from "./types.js";
10
+ import { participantSubjectEnv } from "./types.js";
11
11
  /**
12
12
  * Runs the participants (a dry run runs none). Returns the refusal when real email setup fails, or
13
13
  * the participant outcomes and the warnings the finish records.
14
14
  */
15
15
  export async function runLabParticipants(setup, participants) {
16
- const { plan, input, config, cwd, streams, descriptor, subjectRoute, run } = setup;
17
- const { participantRuns, participantPlan, scrubKnownValues, bundleBase } = setup;
16
+ const { plan, input, cwd, streams, descriptor, run } = setup;
17
+ const { participantRuns, participantPlan, bundleBase } = setup;
18
18
  const { env, knownSecretValues, deps, liveTrace, externalComms, inProgress, fail } = participants;
19
19
  const { dryRun } = plan;
20
- const { inProcessRoute, subjectEnvNames } = subjectRoute;
20
+ const inProcess = plan.runner.desktop === "in-process";
21
+ const subjectEnvNames = [...participantSubjectEnv(plan.runner.subject)];
21
22
  const { runId, paths: runPaths } = run;
22
23
  // A live run writes what it is doing AS IT DOES IT, whether or not anyone is currently watching.
23
24
  // This used to be gated on `options.onObserverReady` — the interactive Observer callback — so a
@@ -46,14 +47,14 @@ export async function runLabParticipants(setup, participants) {
46
47
  streams.showIn(liveObserver);
47
48
  if (input.onObserverReady)
48
49
  await input.onObserverReady(liveObserver);
49
- // Incremental live flush (#441): as each lane's loop reports its recorded-so-far items,
50
+ // Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
50
51
  // rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
51
52
  // Observer's 5s poll sees the timeline grow. The run refuses any snapshot once the final
52
53
  // write began; the route stops the flush timer on every exit below.
53
54
  const liveFlush = startLiveTraceFlush({
54
55
  bundle: inProgressBundle,
55
56
  participantRuns: participantRuns,
56
- model: config.actors[0]?.model ?? DEFAULT_OPENAI_CU_MODEL,
57
+ model: pricedModel(plan.runner.brain),
57
58
  write: (bundle) => run.writeSnapshot(bundle),
58
59
  });
59
60
  liveTrace.flush = liveFlush.flush;
@@ -96,12 +97,12 @@ export async function runLabParticipants(setup, participants) {
96
97
  };
97
98
  }
98
99
  }
99
- // Run lanes (dry-run runs none). In-process is always one lane.
100
+ // Run the participants (dry-run runs none). In-process is always one.
100
101
  let outcomes;
101
102
  let failFastReason;
102
103
  try {
103
104
  if (!dryRun)
104
- ({ outcomes, failFastReason } = await runAllCuaParticipants(participantRuns, deps, participantPlan, inProcessRoute));
105
+ ({ outcomes, failFastReason } = await runAllCuaParticipants(participantRuns, deps, participantPlan, inProcess));
105
106
  }
106
107
  finally {
107
108
  try {
@@ -110,7 +111,7 @@ export async function runLabParticipants(setup, participants) {
110
111
  catch {
111
112
  receivingWarnings.push("Email finalization could not complete. Inspect humanish comms recover; provider cleanup remains unresolved.");
112
113
  }
113
- // Stop the flush timer on every exit, including a throw from the lanes.
114
+ // Stop the flush timer on every exit, including a throw from the participants.
114
115
  await liveTrace.stop?.();
115
116
  }
116
117
  const externalCommsWarnings = !dryRun && externalComms && outcomes !== undefined
@@ -121,7 +122,7 @@ export async function runLabParticipants(setup, participants) {
121
122
  runPaths,
122
123
  participantRuns: participantRuns,
123
124
  outcomes,
124
- scrubKnownValues,
125
+ knownSecretValues,
125
126
  })
126
127
  : [];
127
128
  return {
@@ -1,11 +1,11 @@
1
1
  import type { LabConfig } from "../../lab/types.js";
2
2
  import { type LocalTreeArchive } from "../../subject/local-tree-archive.js";
3
- import { type CuaActorLabHooks } from "./types.js";
3
+ import type { LabDeps } from "../../lab/lab-deps.js";
4
4
  /**
5
5
  * Pack the working tree for a local-tree run and report what left the host on stderr, by counts
6
6
  * and digest only, never paths or file names.
7
7
  */
8
- export declare function packRunLocalTree(hooks: CuaActorLabHooks, config: {
8
+ export declare function packRunLocalTree(deps: LabDeps, config: {
9
9
  readonly subject: Pick<LabConfig["subject"], "localTree">;
10
10
  }, cwd: string): Promise<{
11
11
  archive: LocalTreeArchive;
@@ -14,7 +14,7 @@ export declare function packRunLocalTree(hooks: CuaActorLabHooks, config: {
14
14
  /**
15
15
  * Default local-tree packing implementation: createLocalTreeArchive(root, opts) on the host,
16
16
  * then a single read of the produced archive file into an ArrayBuffer for upload. The DI seam
17
- * (CuaActorLabHooks.packLocalTree) overrides this in deterministic tests so they never require
17
+ * (LabDeps.packLocalTree) overrides this in deterministic tests so they never require
18
18
  * tar/git.
19
19
  */
20
20
  export declare function defaultPackLocalTree(args: {
@@ -1,14 +1,13 @@
1
- // Packing the project's working tree once per local-tree run, on the host, for every lane to upload.
1
+ // Packing the project's working tree once per local-tree run, on the host, for every participant to upload.
2
2
  import { readFile, rm } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { createLocalTreeArchive } from "../../subject/local-tree-archive.js";
5
- import {} from "./types.js";
6
5
  /**
7
6
  * Pack the working tree for a local-tree run and report what left the host on stderr, by counts
8
7
  * and digest only, never paths or file names.
9
8
  */
10
- export async function packRunLocalTree(hooks, config, cwd) {
11
- const packLocalTree = hooks.packLocalTree ?? defaultPackLocalTree;
9
+ export async function packRunLocalTree(deps, config, cwd) {
10
+ const packLocalTree = deps.packLocalTree ?? defaultPackLocalTree;
12
11
  const packed = await packLocalTree({
13
12
  root: cwd,
14
13
  ...(config.subject.localTree?.exclude === undefined
@@ -25,7 +24,7 @@ export async function packRunLocalTree(hooks, config, cwd) {
25
24
  /**
26
25
  * Default local-tree packing implementation: createLocalTreeArchive(root, opts) on the host,
27
26
  * then a single read of the produced archive file into an ArrayBuffer for upload. The DI seam
28
- * (CuaActorLabHooks.packLocalTree) overrides this in deterministic tests so they never require
27
+ * (LabDeps.packLocalTree) overrides this in deterministic tests so they never require
29
28
  * tar/git.
30
29
  */
31
30
  export async function defaultPackLocalTree(args) {