humanish 0.106.1 → 0.108.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 (668) hide show
  1. package/ARCHITECTURE.md +38 -32
  2. package/CHANGELOG.md +28 -0
  3. package/CONTEXT.md +51 -41
  4. package/README.md +152 -174
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-client.js +2 -1
  14. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  15. package/dist/actors/codex/app-server-trace.js +1 -3
  16. package/dist/actors/codex/app-server-ui.js +1 -1
  17. package/dist/actors/codex/app-server.js +2 -1
  18. package/dist/actors/codex/codex-admission.d.ts +91 -0
  19. package/dist/actors/codex/codex-admission.js +150 -0
  20. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  21. package/dist/actors/codex/protocol-compat.js +357 -0
  22. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  23. package/dist/actors/codex/protocol-contract.js +471 -0
  24. package/dist/actors/codex/restricted-executable.d.ts +28 -4
  25. package/dist/actors/codex/restricted-executable.js +104 -29
  26. package/dist/actors/codex/restricted-launch.d.ts +9 -2
  27. package/dist/actors/codex/restricted-launch.js +43 -4
  28. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  29. package/dist/actors/codex/restricted-notifications.js +277 -0
  30. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  31. package/dist/actors/codex/restricted-participant.js +66 -6
  32. package/dist/actors/codex/restricted-policy.d.ts +11 -3
  33. package/dist/actors/codex/restricted-policy.js +2 -2
  34. package/dist/actors/codex/restricted-session.d.ts +16 -3
  35. package/dist/actors/codex/restricted-session.js +60 -22
  36. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  37. package/dist/actors/codex/restricted-transport.js +139 -27
  38. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  39. package/dist/actors/codex/restricted-turn.js +43 -30
  40. package/dist/actors/computer-use/actor.d.ts +17 -17
  41. package/dist/actors/computer-use/actor.js +6 -6
  42. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  43. package/dist/actors/computer-use/admission-limit.js +1 -1
  44. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  45. package/dist/actors/computer-use/loop/actions.js +10 -10
  46. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  47. package/dist/actors/computer-use/loop/backstop.js +15 -13
  48. package/dist/actors/computer-use/loop/ending.d.ts +7 -7
  49. package/dist/actors/computer-use/loop/ending.js +9 -9
  50. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  51. package/dist/actors/computer-use/loop/observation.js +9 -9
  52. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  53. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  54. package/dist/actors/computer-use/loop/session.js +3 -3
  55. package/dist/actors/computer-use/loop/spend.d.ts +2 -2
  56. package/dist/actors/computer-use/loop/spend.js +4 -4
  57. package/dist/actors/computer-use/loop/trace.js +11 -10
  58. package/dist/actors/computer-use/loop/types.d.ts +37 -26
  59. package/dist/actors/computer-use/loop/usage.js +2 -2
  60. package/dist/actors/computer-use/loop.js +4 -4
  61. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  62. package/dist/actors/computer-use/openai-context.js +214 -0
  63. package/dist/actors/computer-use/openai-provider.d.ts +12 -9
  64. package/dist/actors/computer-use/openai-provider.js +47 -36
  65. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  66. package/dist/actors/computer-use/openai-requests.js +82 -15
  67. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  68. package/dist/actors/computer-use/openai-wire.js +36 -34
  69. package/dist/actors/contract.d.ts +86 -49
  70. package/dist/actors/contract.js +29 -23
  71. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  72. package/dist/actors/local-agent/claude-session.js +10 -9
  73. package/dist/actors/local-agent/cli.d.ts +8 -6
  74. package/dist/actors/local-agent/cli.js +24 -28
  75. package/dist/actors/local-agent/readiness.d.ts +2 -2
  76. package/dist/actors/local-agent/readiness.js +4 -4
  77. package/dist/actors/reasoning-effort.js +6 -6
  78. package/dist/actors/registry.d.ts +10 -10
  79. package/dist/actors/registry.js +18 -17
  80. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  81. package/dist/actors/scripted-browser/actor.js +16 -16
  82. package/dist/actors/scripted-browser/browser-command.js +1 -1
  83. package/dist/actors/scripted-browser/journey.js +15 -4
  84. package/dist/actors/scripted-browser/steps.js +19 -1
  85. package/dist/actors/scripted-browser/types.d.ts +12 -2
  86. package/dist/actors/stop-conditions.d.ts +1 -1
  87. package/dist/actors/stop-conditions.js +1 -3
  88. package/dist/analysis/automatic-completion.d.ts +13 -8
  89. package/dist/analysis/automatic-completion.js +14 -8
  90. package/dist/analysis/automatic-config.d.ts +1 -1
  91. package/dist/analysis/automatic-config.js +2 -2
  92. package/dist/analysis/automatic.d.ts +10 -4
  93. package/dist/analysis/automatic.js +17 -13
  94. package/dist/analysis/codex-config.d.ts +6 -2
  95. package/dist/analysis/codex-config.js +22 -14
  96. package/dist/analysis/diagnostics.d.ts +23 -0
  97. package/dist/analysis/diagnostics.js +112 -0
  98. package/dist/analysis/evidence-sources.js +2 -2
  99. package/dist/analysis/evidence.js +6 -6
  100. package/dist/analysis/execute.d.ts +7 -1
  101. package/dist/analysis/execute.js +39 -12
  102. package/dist/analysis/job.d.ts +8 -5
  103. package/dist/analysis/job.js +15 -14
  104. package/dist/analysis/load.d.ts +1 -1
  105. package/dist/analysis/load.js +5 -5
  106. package/dist/analysis/provider.d.ts +9 -1
  107. package/dist/analysis/restricted-codex.d.ts +2 -0
  108. package/dist/analysis/restricted-codex.js +10 -1
  109. package/dist/analysis/service.d.ts +2 -0
  110. package/dist/analysis/service.js +35 -16
  111. package/dist/analysis/sharing.d.ts +2 -2
  112. package/dist/analysis/sharing.js +5 -5
  113. package/dist/analysis/store-executions.d.ts +5 -5
  114. package/dist/analysis/store-executions.js +12 -12
  115. package/dist/analysis/store.d.ts +4 -4
  116. package/dist/analysis/store.js +13 -13
  117. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  118. package/dist/cli/commands/analysis-signals.js +4 -1
  119. package/dist/cli/commands/analyze.js +23 -18
  120. package/dist/cli/commands/codex.js +9 -9
  121. package/dist/cli/commands/comms.js +62 -34
  122. package/dist/cli/commands/feedback.js +20 -21
  123. package/dist/cli/commands/lab-format.d.ts +5 -4
  124. package/dist/cli/commands/lab-format.js +35 -23
  125. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  126. package/dist/cli/commands/lab-route-computer-use.js +32 -21
  127. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  128. package/dist/cli/commands/lab-route-preview.js +7 -7
  129. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  130. package/dist/cli/commands/lab-route-run.js +6 -2
  131. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  132. package/dist/cli/commands/lab-route-scripted.js +0 -1
  133. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  134. package/dist/cli/commands/lab-route-shared-world.js +3 -4
  135. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  136. package/dist/cli/commands/lab-route-terminal.js +0 -1
  137. package/dist/cli/commands/lab-run.js +84 -54
  138. package/dist/cli/commands/lab-scorer.d.ts +2 -4
  139. package/dist/cli/commands/lab-scorer.js +1 -1
  140. package/dist/cli/commands/migrate.d.ts +4 -0
  141. package/dist/cli/commands/migrate.js +65 -0
  142. package/dist/cli/commands/observe.js +168 -107
  143. package/dist/cli/commands/run-command.d.ts +10 -0
  144. package/dist/cli/commands/run-command.js +85 -0
  145. package/dist/cli/commands/run-signals.d.ts +30 -0
  146. package/dist/cli/commands/run-signals.js +146 -0
  147. package/dist/cli/commands/runs.js +137 -136
  148. package/dist/cli/commands/setup.d.ts +2 -2
  149. package/dist/cli/commands/setup.js +26 -21
  150. package/dist/cli/commands/study.d.ts +3 -0
  151. package/dist/cli/commands/study.js +182 -0
  152. package/dist/cli/commands/tui.d.ts +4 -4
  153. package/dist/cli/commands/tui.js +21 -21
  154. package/dist/cli/commands/watch.js +64 -77
  155. package/dist/cli/deprecations.d.ts +18 -0
  156. package/dist/cli/deprecations.js +48 -0
  157. package/dist/cli/doctor.d.ts +18 -5
  158. package/dist/cli/doctor.js +111 -48
  159. package/dist/cli/first-run-path.d.ts +12 -10
  160. package/dist/cli/first-run-path.js +30 -28
  161. package/dist/cli/io.d.ts +46 -10
  162. package/dist/cli/io.js +109 -30
  163. package/dist/cli/observer-follow.d.ts +2 -2
  164. package/dist/cli/observer-follow.js +5 -6
  165. package/dist/cli/orientation.d.ts +6 -3
  166. package/dist/cli/orientation.js +43 -39
  167. package/dist/cli/product-sentence.d.ts +6 -0
  168. package/dist/cli/product-sentence.js +6 -0
  169. package/dist/cli/program.d.ts +6 -1
  170. package/dist/cli/program.js +112 -43
  171. package/dist/cli/telemetry.d.ts +17 -17
  172. package/dist/cli/telemetry.js +49 -41
  173. package/dist/cli.js +1 -1
  174. package/dist/comms/capture-surface.d.ts +14 -13
  175. package/dist/comms/capture-surface.js +23 -22
  176. package/dist/comms/catch-host.d.ts +8 -8
  177. package/dist/comms/catch-host.js +14 -14
  178. package/dist/comms/connections.js +4 -4
  179. package/dist/comms/email-catch.d.ts +3 -3
  180. package/dist/comms/email-catch.js +8 -8
  181. package/dist/comms/external-evidence.d.ts +27 -0
  182. package/dist/comms/external-evidence.js +93 -0
  183. package/dist/comms/extract.js +2 -2
  184. package/dist/comms/fake-inbox.d.ts +2 -2
  185. package/dist/comms/fake-inbox.js +2 -2
  186. package/dist/comms/lease-store.js +7 -7
  187. package/dist/comms/receiving-render.d.ts +1 -1
  188. package/dist/comms/receiving-render.js +2 -2
  189. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  190. package/dist/comms/sandbox-catch-script.js +6 -6
  191. package/dist/comms/sandbox-catch.d.ts +36 -37
  192. package/dist/comms/sandbox-catch.js +34 -35
  193. package/dist/comms/setup.js +42 -8
  194. package/dist/comms/thread-evidence.d.ts +1 -1
  195. package/dist/comms/thread-evidence.js +6 -6
  196. package/dist/comms/types.d.ts +6 -6
  197. package/dist/comms/types.js +4 -4
  198. package/dist/evidence/browser-hygiene.d.ts +1 -1
  199. package/dist/evidence/browser-hygiene.js +1 -1
  200. package/dist/evidence/frame-signature.d.ts +1 -1
  201. package/dist/evidence/frame-signature.js +4 -4
  202. package/dist/evidence/redaction.d.ts +3 -3
  203. package/dist/evidence/redaction.js +5 -5
  204. package/dist/evidence/secret-scrub.d.ts +9 -0
  205. package/dist/evidence/secret-scrub.js +96 -0
  206. package/dist/feedback/draft.js +41 -85
  207. package/dist/feedback/export-bundle.js +5 -5
  208. package/dist/feedback/export.d.ts +5 -1
  209. package/dist/feedback/export.js +16 -17
  210. package/dist/feedback/feedback.d.ts +3 -3
  211. package/dist/feedback/feedback.js +21 -3
  212. package/dist/guest/chromium-text.js +2 -2
  213. package/dist/guest/desktop-native.d.ts +1 -1
  214. package/dist/guest/runtime.js +1 -1
  215. package/dist/index.d.ts +14 -15
  216. package/dist/index.js +10 -11
  217. package/dist/keys/key-resolution.d.ts +7 -5
  218. package/dist/keys/key-resolution.js +40 -38
  219. package/dist/lab/adapter-extension.d.ts +35 -13
  220. package/dist/lab/adapter-extension.js +50 -134
  221. package/dist/lab/adapter-scorer-loader.d.ts +32 -12
  222. package/dist/lab/adapter-scorer-loader.js +56 -32
  223. package/dist/lab/composition-rules.js +58 -58
  224. package/dist/lab/config.js +85 -43
  225. package/dist/lab/deprecated-fields.d.ts +10 -0
  226. package/dist/lab/deprecated-fields.js +24 -0
  227. package/dist/lab/device-presets.d.ts +10 -10
  228. package/dist/lab/device-presets.js +11 -11
  229. package/dist/lab/discover.d.ts +13 -9
  230. package/dist/lab/discover.js +118 -60
  231. package/dist/lab/doctor.d.ts +53 -11
  232. package/dist/lab/doctor.js +193 -47
  233. package/dist/lab/init-plan.js +1 -3
  234. package/dist/lab/init-templates.js +147 -147
  235. package/dist/lab/init.d.ts +1 -1
  236. package/dist/lab/init.js +41 -9
  237. package/dist/lab/keys.d.ts +2 -0
  238. package/dist/lab/keys.js +43 -9
  239. package/dist/lab/lab-deps.d.ts +80 -0
  240. package/dist/lab/lab-deps.js +4 -0
  241. package/dist/lab/parse/actors.js +17 -16
  242. package/dist/lab/parse/comms.js +8 -7
  243. package/dist/lab/parse/execution.js +15 -14
  244. package/dist/lab/parse/study-v3.d.ts +23 -0
  245. package/dist/lab/parse/study-v3.js +259 -0
  246. package/dist/lab/parse/subject-state.d.ts +7 -7
  247. package/dist/lab/parse/subject-state.js +18 -17
  248. package/dist/lab/parse/subject.js +30 -29
  249. package/dist/lab/parse/values.d.ts +1 -2
  250. package/dist/lab/parse/values.js +3 -6
  251. package/dist/lab/persona-resolve.d.ts +7 -7
  252. package/dist/lab/persona-resolve.js +8 -8
  253. package/dist/lab/persona.js +1 -3
  254. package/dist/lab/plan-base.d.ts +0 -2
  255. package/dist/lab/plan-base.js +6 -4
  256. package/dist/lab/plan-participants.d.ts +7 -7
  257. package/dist/lab/plan-participants.js +2 -2
  258. package/dist/lab/plan-types.d.ts +26 -8
  259. package/dist/lab/plan.d.ts +4 -18
  260. package/dist/lab/plan.js +24 -79
  261. package/dist/lab/preflight-probes.js +11 -11
  262. package/dist/lab/preflight-result.d.ts +2 -1
  263. package/dist/lab/preflight-result.js +5 -6
  264. package/dist/lab/preflight.d.ts +7 -8
  265. package/dist/lab/preflight.js +6 -6
  266. package/dist/lab/requirements.d.ts +20 -0
  267. package/dist/lab/requirements.js +54 -0
  268. package/dist/lab/route-inputs.d.ts +23 -12
  269. package/dist/lab/route-inputs.js +48 -51
  270. package/dist/lab/routing.d.ts +42 -41
  271. package/dist/lab/routing.js +66 -68
  272. package/dist/lab/run-lab-events.d.ts +3 -11
  273. package/dist/lab/run-lab-events.js +2 -16
  274. package/dist/lab/run-lab-homes.d.ts +76 -0
  275. package/dist/lab/run-lab-homes.js +7 -0
  276. package/dist/lab/run-lab-options.d.ts +12 -66
  277. package/dist/lab/run-lab-options.js +58 -285
  278. package/dist/lab/summary.d.ts +15 -9
  279. package/dist/lab/summary.js +24 -17
  280. package/dist/lab/tasks.d.ts +15 -15
  281. package/dist/lab/tasks.js +14 -14
  282. package/dist/lab/types.d.ts +201 -195
  283. package/dist/lab/types.js +2 -0
  284. package/dist/lab/validation.d.ts +21 -21
  285. package/dist/lab/validation.js +61 -59
  286. package/dist/lab/warnings.d.ts +10 -0
  287. package/dist/lab/warnings.js +70 -41
  288. package/dist/library-aliases.d.ts +56 -0
  289. package/dist/library-aliases.js +22 -0
  290. package/dist/observer/artifact.d.ts +2 -2
  291. package/dist/observer/artifact.js +9 -9
  292. package/dist/observer/data.d.ts +6 -6
  293. package/dist/observer/data.js +7 -6
  294. package/dist/observer/exposure.d.ts +1 -1
  295. package/dist/observer/exposure.js +11 -11
  296. package/dist/observer/http.js +1 -1
  297. package/dist/observer/library.d.ts +1 -1
  298. package/dist/observer/library.js +4 -2
  299. package/dist/observer/listen.js +5 -4
  300. package/dist/observer/render.d.ts +1 -1
  301. package/dist/observer/render.js +12 -7
  302. package/dist/observer/run-routes.d.ts +4 -4
  303. package/dist/observer/run-routes.js +6 -6
  304. package/dist/observer/serve.d.ts +17 -0
  305. package/dist/observer/serve.js +41 -6
  306. package/dist/observer/tunnel.js +1 -1
  307. package/dist/observer-app.html +4 -4
  308. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  309. package/dist/routes/computer-use/bundle-parts.js +24 -17
  310. package/dist/routes/computer-use/bundle.d.ts +4 -11
  311. package/dist/routes/computer-use/bundle.js +12 -18
  312. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  313. package/dist/routes/computer-use/diagnostics.js +1 -1
  314. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +11 -11
  315. package/dist/routes/computer-use/e2b-desktop/comms.js +24 -27
  316. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  317. package/dist/routes/computer-use/e2b-desktop/desktop.js +8 -11
  318. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +16 -15
  319. package/dist/routes/computer-use/e2b-desktop/fidelity.js +20 -19
  320. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  321. package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -43
  322. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  323. package/dist/routes/computer-use/e2b-desktop/start.js +32 -30
  324. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  325. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  326. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  327. package/dist/routes/computer-use/e2b-desktop/teardown.js +33 -20
  328. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  329. package/dist/routes/computer-use/external-comms.js +19 -43
  330. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  331. package/dist/routes/computer-use/fanout-bundle.js +38 -42
  332. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +33 -28
  333. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  334. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  335. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  336. package/dist/routes/computer-use/live-flush.js +20 -28
  337. package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +4 -2
  338. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +17 -16
  339. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  340. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  341. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  342. package/dist/routes/computer-use/local-vm.js +40 -67
  343. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  344. package/dist/routes/computer-use/participant-desktop.js +5 -25
  345. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +11 -11
  346. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +39 -26
  347. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  348. package/dist/routes/computer-use/participant-facts.js +12 -1
  349. package/dist/routes/computer-use/participant-model.d.ts +25 -11
  350. package/dist/routes/computer-use/participant-model.js +76 -34
  351. package/dist/routes/computer-use/participant-prompt.d.ts +13 -13
  352. package/dist/routes/computer-use/participant-prompt.js +8 -8
  353. package/dist/routes/computer-use/participant-runs.d.ts +11 -11
  354. package/dist/routes/computer-use/participant-runs.js +18 -18
  355. package/dist/routes/computer-use/plan.d.ts +21 -29
  356. package/dist/routes/computer-use/plan.js +70 -78
  357. package/dist/routes/computer-use/preflight.d.ts +3 -5
  358. package/dist/routes/computer-use/preflight.js +40 -36
  359. package/dist/routes/computer-use/rerun-selection.js +11 -7
  360. package/dist/routes/computer-use/result.d.ts +1 -1
  361. package/dist/routes/computer-use/result.js +48 -38
  362. package/dist/routes/computer-use/route.d.ts +5 -5
  363. package/dist/routes/computer-use/route.js +36 -33
  364. package/dist/routes/computer-use/self-report.d.ts +8 -8
  365. package/dist/routes/computer-use/self-report.js +33 -33
  366. package/dist/routes/computer-use/setup.d.ts +9 -15
  367. package/dist/routes/computer-use/setup.js +106 -83
  368. package/dist/routes/computer-use/single-bundle.d.ts +13 -16
  369. package/dist/routes/computer-use/single-bundle.js +46 -53
  370. package/dist/routes/computer-use/subject-projection.d.ts +6 -8
  371. package/dist/routes/computer-use/subject-projection.js +24 -23
  372. package/dist/routes/computer-use/types.d.ts +195 -238
  373. package/dist/routes/computer-use/types.js +21 -13
  374. package/dist/routes/preview.d.ts +8 -2
  375. package/dist/routes/preview.js +8 -5
  376. package/dist/routes/scripted/bundle.d.ts +5 -8
  377. package/dist/routes/scripted/bundle.js +23 -27
  378. package/dist/routes/scripted/plan.d.ts +6 -8
  379. package/dist/routes/scripted/plan.js +15 -13
  380. package/dist/routes/scripted/result.d.ts +4 -1
  381. package/dist/routes/scripted/result.js +15 -11
  382. package/dist/routes/scripted/route.js +15 -17
  383. package/dist/routes/scripted/scenario.d.ts +1 -1
  384. package/dist/routes/scripted/scenario.js +3 -3
  385. package/dist/routes/scripted/setup.d.ts +3 -2
  386. package/dist/routes/scripted/setup.js +27 -26
  387. package/dist/routes/scripted/subject.d.ts +8 -3
  388. package/dist/routes/scripted/subject.js +10 -6
  389. package/dist/routes/scripted/surface-records.js +4 -4
  390. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  391. package/dist/routes/scripted/surface-sessions.js +4 -4
  392. package/dist/routes/scripted/types.d.ts +21 -40
  393. package/dist/routes/scripted/types.js +2 -3
  394. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +17 -16
  395. package/dist/routes/shared-world/bundle.d.ts +7 -7
  396. package/dist/routes/shared-world/bundle.js +60 -62
  397. package/dist/routes/shared-world/checkpoints.d.ts +5 -5
  398. package/dist/routes/shared-world/checkpoints.js +5 -5
  399. package/dist/routes/shared-world/comms.d.ts +8 -7
  400. package/dist/routes/shared-world/comms.js +38 -51
  401. package/dist/routes/shared-world/external-public.d.ts +6 -5
  402. package/dist/routes/shared-world/external-public.js +28 -25
  403. package/dist/routes/shared-world/handoff.d.ts +10 -9
  404. package/dist/routes/shared-world/handoff.js +89 -81
  405. package/dist/routes/shared-world/lobby-code.d.ts +7 -7
  406. package/dist/routes/shared-world/lobby-code.js +22 -22
  407. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +15 -12
  408. package/dist/routes/shared-world/{seats.js → participant-specs.js} +65 -63
  409. package/dist/routes/shared-world/plan.d.ts +2 -6
  410. package/dist/routes/shared-world/plan.js +8 -9
  411. package/dist/routes/shared-world/provenance.d.ts +4 -4
  412. package/dist/routes/shared-world/provenance.js +4 -4
  413. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  414. package/dist/routes/shared-world/provisioned.js +55 -48
  415. package/dist/routes/shared-world/result.js +47 -36
  416. package/dist/routes/shared-world/route.js +54 -57
  417. package/dist/routes/shared-world/setup.d.ts +6 -5
  418. package/dist/routes/shared-world/setup.js +16 -18
  419. package/dist/routes/shared-world/types.d.ts +70 -141
  420. package/dist/routes/shared-world/types.js +5 -5
  421. package/dist/routes/terminal/adapter.d.ts +10 -10
  422. package/dist/routes/terminal/adapter.js +32 -129
  423. package/dist/routes/terminal/bundle.d.ts +10 -15
  424. package/dist/routes/terminal/bundle.js +43 -52
  425. package/dist/routes/terminal/credentials.d.ts +4 -4
  426. package/dist/routes/terminal/credentials.js +20 -20
  427. package/dist/routes/terminal/dry-run.d.ts +1 -1
  428. package/dist/routes/terminal/dry-run.js +13 -15
  429. package/dist/routes/terminal/encoding.d.ts +1 -1
  430. package/dist/routes/terminal/encoding.js +4 -4
  431. package/dist/routes/terminal/ledger.d.ts +8 -8
  432. package/dist/routes/terminal/ledger.js +22 -22
  433. package/dist/routes/terminal/live-finish.d.ts +1 -2
  434. package/dist/routes/terminal/live-finish.js +24 -23
  435. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  436. package/dist/routes/terminal/live-sandbox.js +31 -32
  437. package/dist/routes/terminal/participant-text.d.ts +23 -0
  438. package/dist/routes/terminal/participant-text.js +165 -0
  439. package/dist/routes/terminal/persona.js +1 -1
  440. package/dist/routes/terminal/plan.d.ts +2 -6
  441. package/dist/routes/terminal/plan.js +23 -19
  442. package/dist/routes/terminal/recorder.d.ts +6 -1
  443. package/dist/routes/terminal/recorder.js +12 -4
  444. package/dist/routes/terminal/result.js +12 -12
  445. package/dist/routes/terminal/route.js +30 -31
  446. package/dist/routes/terminal/runtime.d.ts +3 -2
  447. package/dist/routes/terminal/runtime.js +3 -3
  448. package/dist/routes/terminal/sandbox.d.ts +4 -4
  449. package/dist/routes/terminal/sandbox.js +10 -10
  450. package/dist/routes/terminal/session.js +22 -19
  451. package/dist/routes/terminal/token-usage.d.ts +1 -1
  452. package/dist/routes/terminal/token-usage.js +10 -11
  453. package/dist/routes/terminal/trace.d.ts +7 -10
  454. package/dist/routes/terminal/trace.js +11 -66
  455. package/dist/routes/terminal/types.d.ts +104 -114
  456. package/dist/routes/terminal/types.js +12 -7
  457. package/dist/run/active-runs.d.ts +13 -0
  458. package/dist/run/active-runs.js +12 -0
  459. package/dist/run/bundle-shape.d.ts +2 -1
  460. package/dist/run/bundle-shape.js +7 -7
  461. package/dist/run/bundle.d.ts +99 -92
  462. package/dist/run/bundle.js +10 -8
  463. package/dist/run/cost-summary.js +6 -5
  464. package/dist/run/costs.d.ts +6 -6
  465. package/dist/run/costs.js +17 -11
  466. package/dist/run/detail.d.ts +9 -9
  467. package/dist/run/detail.js +10 -10
  468. package/dist/run/dry-run-inputs.js +1 -1
  469. package/dist/run/dry-run.js +23 -30
  470. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  471. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  472. package/dist/run/feedback-shape.js +1 -1
  473. package/dist/run/judge.d.ts +34 -16
  474. package/dist/run/judge.js +41 -14
  475. package/dist/run/locate.d.ts +2 -0
  476. package/dist/run/locate.js +3 -1
  477. package/dist/run/outcomes.d.ts +3 -3
  478. package/dist/run/outcomes.js +3 -3
  479. package/dist/run/participant-records.d.ts +2 -2
  480. package/dist/run/participant-records.js +2 -2
  481. package/dist/run/paths.d.ts +1 -1
  482. package/dist/run/paths.js +2 -2
  483. package/dist/run/pricing.d.ts +30 -15
  484. package/dist/run/pricing.js +49 -30
  485. package/dist/run/projection.d.ts +27 -27
  486. package/dist/run/projection.js +23 -23
  487. package/dist/run/reclaim.d.ts +6 -0
  488. package/dist/run/reclaim.js +15 -5
  489. package/dist/run/results.d.ts +5 -5
  490. package/dist/run/run-index.d.ts +9 -7
  491. package/dist/run/run-index.js +24 -25
  492. package/dist/run/run-not-found.d.ts +5 -0
  493. package/dist/run/run-not-found.js +15 -0
  494. package/dist/run/run.d.ts +7 -4
  495. package/dist/run/run.js +10 -6
  496. package/dist/run/sandbox-receipts.d.ts +5 -5
  497. package/dist/run/sandbox-receipts.js +6 -6
  498. package/dist/run/shared-world-evidence.d.ts +67 -66
  499. package/dist/run/shared-world-evidence.js +4 -4
  500. package/dist/run/shared-world-shape.d.ts +3 -3
  501. package/dist/run/shared-world-shape.js +16 -16
  502. package/dist/run/stats.d.ts +17 -11
  503. package/dist/run/stats.js +124 -66
  504. package/dist/run/status.d.ts +21 -32
  505. package/dist/run/status.js +34 -33
  506. package/dist/run/stored-runs.js +2 -1
  507. package/dist/run/stream-shape.js +1 -1
  508. package/dist/run/streams.d.ts +29 -22
  509. package/dist/run/study-provenance.d.ts +47 -0
  510. package/dist/run/study-provenance.js +63 -0
  511. package/dist/run/study-result.d.ts +16 -0
  512. package/dist/run/study-result.js +9 -0
  513. package/dist/run/terminal-contract.d.ts +5 -5
  514. package/dist/run/terminal-contract.js +4 -4
  515. package/dist/run/text.d.ts +2 -0
  516. package/dist/run/text.js +4 -0
  517. package/dist/run/transient-comms-secrets.d.ts +5 -0
  518. package/dist/run/transient-comms-secrets.js +12 -0
  519. package/dist/run-lab.d.ts +40 -38
  520. package/dist/run-lab.js +42 -40
  521. package/dist/study/convert.d.ts +33 -0
  522. package/dist/study/convert.js +432 -0
  523. package/dist/study/field-paths.d.ts +12 -0
  524. package/dist/study/field-paths.js +126 -0
  525. package/dist/study/files.d.ts +26 -0
  526. package/dist/study/files.js +43 -0
  527. package/dist/study/migrate.d.ts +48 -0
  528. package/dist/study/migrate.js +408 -0
  529. package/dist/study/owned-files.d.ts +38 -0
  530. package/dist/study/owned-files.js +182 -0
  531. package/dist/subject/clone.d.ts +1 -1
  532. package/dist/subject/desktop-cli.d.ts +2 -2
  533. package/dist/subject/desktop-cli.js +3 -3
  534. package/dist/subject/local-tree-archive.d.ts +1 -1
  535. package/dist/subject/local-tree-archive.js +5 -5
  536. package/dist/subject/local-tree.d.ts +3 -3
  537. package/dist/subject/local-tree.js +1 -1
  538. package/dist/subject/node-bootstrap.d.ts +1 -1
  539. package/dist/subject/node-bootstrap.js +4 -4
  540. package/dist/subject/runtime.js +10 -11
  541. package/dist/subject/serve.d.ts +1 -1
  542. package/dist/subject/serve.js +4 -4
  543. package/dist/subject/state.d.ts +1 -1
  544. package/dist/subject/steps.d.ts +8 -8
  545. package/dist/subject/steps.js +7 -7
  546. package/dist/substrates/command-failure.d.ts +3 -3
  547. package/dist/substrates/command-failure.js +3 -3
  548. package/dist/substrates/detached.d.ts +6 -6
  549. package/dist/substrates/detached.js +7 -7
  550. package/dist/substrates/e2b/cdp-probe.d.ts +11 -11
  551. package/dist/substrates/e2b/cdp-probe.js +15 -18
  552. package/dist/substrates/e2b/desktop-browser.d.ts +5 -5
  553. package/dist/substrates/e2b/desktop-browser.js +12 -12
  554. package/dist/substrates/e2b/desktop-cdp.d.ts +15 -15
  555. package/dist/substrates/e2b/desktop-cdp.js +11 -11
  556. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  557. package/dist/substrates/e2b/desktop-executor.js +1 -1
  558. package/dist/substrates/e2b/desktop-geometry.d.ts +6 -6
  559. package/dist/substrates/e2b/desktop-geometry.js +9 -9
  560. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  561. package/dist/substrates/e2b/desktop-media.js +3 -3
  562. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  563. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  564. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  565. package/dist/substrates/e2b/sandbox.js +2 -2
  566. package/dist/substrates/e2b/sdk.d.ts +11 -11
  567. package/dist/substrates/e2b/sdk.js +8 -8
  568. package/dist/substrates/local/runtime-host.d.ts +2 -0
  569. package/dist/substrates/local/runtime-host.js +6 -0
  570. package/dist/tui/actions.d.ts +8 -6
  571. package/dist/tui/actions.js +31 -22
  572. package/dist/tui/contract.d.ts +16 -16
  573. package/dist/tui/contract.js +10 -10
  574. package/dist/tui/launch.d.ts +4 -4
  575. package/dist/tui/launch.js +18 -19
  576. package/dist/tui/project.js +5 -5
  577. package/dist/tui-app.js +83 -83
  578. package/dist/verify/actor.d.ts +14 -14
  579. package/dist/verify/actor.js +45 -45
  580. package/dist/verify/artifacts.d.ts +3 -3
  581. package/dist/verify/artifacts.js +6 -6
  582. package/dist/verify/context-growth.d.ts +9 -0
  583. package/dist/verify/context-growth.js +62 -0
  584. package/dist/verify/costs.d.ts +7 -7
  585. package/dist/verify/costs.js +9 -9
  586. package/dist/verify/liveness.d.ts +1 -1
  587. package/dist/verify/liveness.js +4 -1
  588. package/dist/verify/rerun.d.ts +1 -1
  589. package/dist/verify/rerun.js +1 -1
  590. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  591. package/dist/verify/shared-world-concurrent.js +79 -76
  592. package/dist/verify/shared-world.d.ts +2 -2
  593. package/dist/verify/shared-world.js +18 -18
  594. package/dist/verify/subject.d.ts +4 -4
  595. package/dist/verify/subject.js +18 -18
  596. package/dist/verify/verify.js +98 -49
  597. package/docs/README.md +26 -33
  598. package/docs/architecture/actor-contract.md +105 -98
  599. package/docs/architecture/desktop-sessions.md +14 -14
  600. package/docs/architecture/external-public-shared-world.md +66 -59
  601. package/docs/architecture/github-feedback-loop.md +1 -4
  602. package/docs/architecture/guest-desktop.md +2 -2
  603. package/docs/architecture/observer.md +37 -37
  604. package/docs/architecture/restricted-codex-analysis.md +70 -30
  605. package/docs/architecture/serve.md +34 -37
  606. package/docs/architecture/state-driven-executor.md +55 -59
  607. package/docs/architecture/task-protocol-support.md +7 -9
  608. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +83 -115
  609. package/docs/contracts/README.md +24 -0
  610. package/docs/contracts/adapter-admission.md +3 -3
  611. package/docs/contracts/adapter-fixtures.md +2 -5
  612. package/docs/contracts/core.md +1 -3
  613. package/docs/contracts/errors.md +62 -0
  614. package/docs/contracts/feedback.md +8 -9
  615. package/docs/contracts/policy.md +7 -12
  616. package/docs/contracts/run-bundle.md +54 -51
  617. package/docs/contracts/schemas.md +505 -390
  618. package/docs/contracts/study-analysis.md +26 -2
  619. package/docs/contracts/study-costs.md +11 -7
  620. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  621. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  622. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  623. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  624. package/docs/principles/actor-fidelity.md +4 -4
  625. package/docs/principles/engineering.md +3 -3
  626. package/docs/principles/invariants-and-defaults.md +38 -38
  627. package/docs/principles/self-driving-harness.md +1 -5
  628. package/docs/principles/three-roles.md +1 -1
  629. package/docs/product/automatic-analysis.md +8 -7
  630. package/examples/participant/README.md +5 -5
  631. package/examples/participant/run.mjs +11 -10
  632. package/examples/scorer/README.md +3 -3
  633. package/examples/scorer/run.mjs +11 -12
  634. package/package.json +16 -17
  635. package/skills/humanish/SKILL.md +63 -60
  636. package/skills/humanish/agents/openai.yaml +1 -1
  637. package/AGENTS.md +0 -99
  638. package/CONTRIBUTING.md +0 -148
  639. package/dist/actors/codex/qualified-versions.d.ts +0 -45
  640. package/dist/actors/codex/qualified-versions.js +0 -87
  641. package/dist/cli/commands/lab.d.ts +0 -3
  642. package/dist/cli/commands/lab.js +0 -193
  643. package/dist/deprecated.d.ts +0 -90
  644. package/dist/deprecated.js +0 -106
  645. package/dist/lab/bag-overrides.d.ts +0 -18
  646. package/dist/lab/bag-overrides.js +0 -121
  647. package/dist/observer/static.d.ts +0 -39
  648. package/dist/observer/static.js +0 -369
  649. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  650. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  651. package/docs/architecture/comms-inbox.md +0 -122
  652. package/docs/architecture/desktop-recording.md +0 -80
  653. package/docs/architecture/local-browser-runtime.md +0 -178
  654. package/docs/architecture/observer-review.md +0 -144
  655. package/docs/architecture/participant-media.md +0 -90
  656. package/docs/architecture/project-layout.md +0 -62
  657. package/docs/architecture/real-email-receiving.md +0 -136
  658. package/docs/assets/humanish-drawdb-hero.png +0 -0
  659. package/docs/assets/humanish-observer-hero.png +0 -0
  660. package/docs/goals/current.md +0 -207
  661. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  662. package/docs/product/open-source-install-experience.md +0 -240
  663. package/docs/ramp/README.md +0 -294
  664. package/docs/release/open-source-readiness.md +0 -222
  665. package/docs/release/public-readiness-standard.md +0 -210
  666. package/docs/roadmap/world-class-open-source-v0.md +0 -311
  667. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  668. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -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: once per run, after every participant finished, because 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: once per run, after every participant finished, because 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
  */
@@ -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,33 +32,33 @@ 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
- // What happened to the PARTICIPANTS, with the denominator attached. The verdict above has to
38
+ // What happened to the participants, with the denominator attached. The verdict above has to
39
39
  // collapse the run to one word; this does not (docs/principles/three-roles.md).
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
- // 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
45
+ // count it, but `reachedGoal` was reading the trace status directly, so one run could be both
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,
50
50
  selfReportedBlocker: outcome.selfReportedBlocker === true,
51
51
  })),
52
- // A participant who reached the goal AND told you the road there was broken is the most
52
+ // A participant who reached the goal and told you the road there was broken is the most
53
53
  // useful result a study produces; reporting only the outcome would bury it.
54
54
  terminalOutcomes.map((outcome) => outcome.reportedFriction === true))
55
55
  : undefined;
56
56
  // The study funnel: per-task completion rates across every session that measured one. This is
57
- // "where did people get stuck" as data, next to WHO got stuck (participants) above.
57
+ // "where did people get stuck" as data, next to who got stuck (participants) above.
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,16 +70,16 @@ 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
- ? `${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)}` : ""}.`,
77
+ ? `${args.rerun ? `Rerun from ${args.rerun.sourceRunId}: ` : ""}Dry-run fan-out: ${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)}` : ""}${runTasks ? `; tasks: ${formatRunTaskFunnel(runTasks)}` : ""}.`,
79
79
  gaps: args.inProgress === true
80
80
  ? ["Live fan-out session is still running."]
81
81
  : args.dryRun
82
- ? ["Live fan-out session not yet run (dry-run contract only)."]
82
+ ? ["Live fan-out session not yet run (dry run only)."]
83
83
  : specs
84
84
  .map((spec, index) => ({ spec, outcome: outcomes?.[index] }))
85
85
  .filter(({ outcome }) => outcome === undefined ||
@@ -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,45 +204,41 @@ 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: {
223
219
  id: specs[0].persona.id,
224
220
  name: `Computer-use fan-out (${specs.length} participants)`,
225
- source: `lab:${plan.labId}`,
221
+ source: `study:${plan.labId}`,
226
222
  sourceDigest: specs[0].persona.promptDigest,
227
223
  },
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
- // this writer produced. The only adopter-side workaround was scanner evasion (#412).
232
+ // this writer produced. The only adopter-side workaround was scanner evasion.
237
233
  //
238
234
  // The instructions the model actually receives are untouched; only the persisted copy changes.
239
235
  goal: redactText(specs[0].evidenceInstructions ?? specs[0].instructions),
240
- source: `lab:${plan.labId}`,
236
+ source: `study:${plan.labId}`,
241
237
  sourceDigest: specs[0].persona.promptDigest,
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
  },
@@ -255,14 +251,14 @@ export function buildCuaFanoutBundle(args) {
255
251
  status: "passed",
256
252
  notes: ranLive
257
253
  ? anyRaw
258
- ? "Typed text recorded as length only and reasoning/messages pass through text redaction. Some participants captured FULL-FIDELITY (raw) screenshots, retained for local use and NOT redacted for publishing; set policies.redactScreenshots: true to blur a share-as-is bundle."
254
+ ? "Typed text is recorded as its length only, and reasoning and messages pass through text redaction. Some participants captured unblurred screenshots, kept for local use and not redacted for publishing. Set policies.redactScreenshots: true to blur screenshots in a bundle you plan to share."
259
255
  : "Typed text recorded as length only and reasoning/messages pass through text redaction. Screenshots are blurred at capture (policies.redactScreenshots: true) for a share-as-is bundle."
260
- : "Dry-run fan-out contract bundle: no desktops launched and no screenshots captured. Typed text is recorded as length only and reasoning/messages pass through text redaction whenever a session runs.",
256
+ : "Dry-run fan-out bundle: no desktops launched and no screenshots captured. Typed text is recorded as length only and reasoning/messages pass through text redaction whenever a session runs.",
261
257
  },
262
258
  artifacts: bundleArtifacts(),
263
259
  review,
264
- // What the participants reported, when any reported anything (#392). Dry-run and in-progress
265
- // bundles carry none — there is no participant yet to quote.
260
+ // What the participants reported, when any reported anything. Dry-run and in-progress
261
+ // bundles carry none: there is no participant yet to quote.
266
262
  feedbackCandidates: fanoutFeedbackCandidates(args),
267
263
  // Selected hosted image, including the optional speech default; omitted on the stock desktop.
268
264
  ...(desktopTemplate === undefined ? {} : { desktopTemplate }),
@@ -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];
@@ -37,7 +41,7 @@ function fanoutParticipantView(args, spec, index) {
37
41
  : (outcome?.skippedReason ??
38
42
  session?.reason ??
39
43
  outcome?.sessionError ??
40
- "Contract bundle only: dry-run produced the evidence shape without launching a desktop or spending provider tokens.");
44
+ "Dry run: the evidence shape was written without launching a desktop or spending provider tokens.");
41
45
  const traceScreenshotMode = session?.trace.redaction.screenshots;
42
46
  const screenshotMode = traceScreenshotMode === "raw" || traceScreenshotMode === "blurred"
43
47
  ? traceScreenshotMode
@@ -76,15 +80,15 @@ function fanoutParticipantRecord(args, spec, index, view) {
76
80
  ? `Participant ${spec.planned.id} ${outcome.skippedReason}.`
77
81
  : outcome?.sessionError !== undefined
78
82
  ? `Participant ${spec.planned.id} failed before a terminal session verdict: ${outcome.sessionError}`
79
- : `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,
83
+ : `Participant ${spec.planned.id} (${spec.persona.id}/${spec.planned.device.name}) for ${args.descriptor.id} against ${publicTargetUrl}; no session ran.`,
84
+ startedAt: args.run.createdAt,
85
+ updatedAt: args.run.createdAt,
82
86
  });
83
87
  }
84
88
  function fanoutParticipantStream(args, spec, view) {
85
- const { plan } = args;
86
89
  const { outcome, publicTargetUrl, session, desktopGeometry, screenshots } = view;
87
90
  const { lastScreenshot, status, reason, screenshotMode } = view;
91
+ const judged = outcome === undefined ? undefined : judgedStatus(participantFactsOf(outcome));
88
92
  return participantStream(spec, {
89
93
  ...(spec.evidenceAssignment === undefined
90
94
  ? {}
@@ -99,17 +103,18 @@ function fanoutParticipantStream(args, spec, view) {
99
103
  ? {}
100
104
  : { caseGroup: spec.planned.labels.caseGroup }),
101
105
  kind: "browser",
102
- label: `CUA participant ${spec.planned.id}: ${plan.labId}`,
106
+ label: `${spec.planned.id} · browser`,
103
107
  status,
108
+ ...(judged === undefined ? {} : { judgedStatus: judged }),
104
109
  transport: "snapshot",
105
- updatedAt: args.createdAt,
110
+ updatedAt: args.run.createdAt,
106
111
  embed: lastScreenshot
107
112
  ? {
108
113
  kind: "screenshot",
109
114
  url: lastScreenshot,
110
- title: `CUA desktop ${spec.planned.id} (${screenshotMode})`,
115
+ title: `Desktop (${screenshotMode})`,
111
116
  }
112
- : { kind: "placeholder", title: `CUA desktop ${spec.planned.id}` },
117
+ : { kind: "placeholder", title: "Desktop" },
113
118
  ...(desktopGeometry.viewport === undefined
114
119
  ? {}
115
120
  : {
@@ -174,41 +179,41 @@ function fanoutSubjectEvents(ctx, spec, view) {
174
179
  const { publicTargetUrl, subject, session } = view;
175
180
  const events = [];
176
181
  const record = (event) => events.push(participantEvent(spec, event));
177
- // Per-lane subject provenance (invariant 5).
178
- if (args.cloneRoute && args.publicRepo) {
182
+ // Per-participant subject provenance.
183
+ if (args.plan.runner.subject.kind === "clone" && args.publicRepo) {
179
184
  record({
180
185
  id: nextEventId(`subject-${spec.planned.id}`),
181
- at: args.createdAt,
186
+ at: args.run.createdAt,
182
187
  level: "info",
183
188
  type: "cua-lab.subject.provenance",
184
189
  message: `Participant ${spec.planned.id}: ${args.dryRun
185
- ? `subject declared: clone of ${args.publicRepo}, served at ${publicTargetUrl} in-sandbox (dry-run contract; nothing cloned)`
190
+ ? `subject declared: clone of ${args.publicRepo}, served at ${publicTargetUrl} in-sandbox (dry run; nothing cloned)`
186
191
  : subject.commit
187
192
  ? session
188
193
  ? `subject cloned from ${args.publicRepo}@${subject.commit} and served at ${publicTargetUrl} in-sandbox`
189
194
  : `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)}.`,
195
+ : `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
196
  });
192
197
  }
193
198
  else if (subject.source === "local-tree") {
194
199
  record({
195
200
  id: nextEventId(`subject-${spec.planned.id}`),
196
- at: args.createdAt,
201
+ at: args.run.createdAt,
197
202
  level: "info",
198
203
  type: "cua-lab.subject.provenance",
199
204
  message: `Participant ${spec.planned.id}: ${args.dryRun
200
- ? `subject declared: local working tree, to be packed and served at ${publicTargetUrl} in-sandbox (dry-run contract; nothing packed)`
205
+ ? `subject declared: local working tree, to be packed and served at ${publicTargetUrl} in-sandbox (dry run; nothing packed)`
201
206
  : subject.archiveSha256
202
207
  ? session
203
208
  ? `subject packed (archiveSha256 ${subject.archiveSha256}${subject.dirty === true ? ", dirty working tree" : subject.dirty === false ? ", clean working tree" : ""}) and served at ${publicTargetUrl} in-sandbox`
204
209
  : `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)}.`,
210
+ : "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
211
  });
207
212
  }
208
213
  else {
209
214
  record({
210
215
  id: nextEventId(`subject-${spec.planned.id}`),
211
- at: args.createdAt,
216
+ at: args.run.createdAt,
212
217
  level: "info",
213
218
  type: "cua-lab.subject.declared",
214
219
  message: `Participant ${spec.planned.id}: subject app declared at ${publicTargetUrl} (loopback inside the participant's own desktop sandbox).`,
@@ -221,11 +226,11 @@ function fanoutOutcomeEvents(ctx, spec, view) {
221
226
  const { outcome, session, desktopGeometry } = view;
222
227
  const events = [];
223
228
  const record = (event) => events.push(participantEvent(spec, event));
224
- // Per-lane session event.
229
+ // Per-participant session event.
225
230
  if (session) {
226
231
  record({
227
232
  id: nextEventId(`session-${spec.planned.id}`),
228
- at: args.createdAt,
233
+ at: args.run.createdAt,
229
234
  level: session.status === "passed" ? "info" : "warn",
230
235
  type: `cua-lab.session.${session.completionReason}`,
231
236
  message: `Participant ${spec.planned.id} ${session.status}: ${session.reason}`,
@@ -234,7 +239,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
234
239
  else if (args.inProgress === true && outcome === undefined) {
235
240
  record({
236
241
  id: nextEventId(`running-${spec.planned.id}`),
237
- at: args.createdAt,
242
+ at: args.run.createdAt,
238
243
  level: "info",
239
244
  type: "cua-lab.session.running",
240
245
  message: `Participant ${spec.planned.id}: live computer-use session is running; terminal evidence has not been written yet.`,
@@ -243,7 +248,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
243
248
  else if (outcome?.skippedReason !== undefined) {
244
249
  record({
245
250
  id: nextEventId(`blocked-${spec.planned.id}`),
246
- at: args.createdAt,
251
+ at: args.run.createdAt,
247
252
  level: "warn",
248
253
  type: "cua-lab.session.blocked",
249
254
  message: `Participant ${spec.planned.id} ${outcome.skippedReason}.`,
@@ -252,7 +257,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
252
257
  else if (outcome?.sessionError !== undefined) {
253
258
  record({
254
259
  id: nextEventId(`session-error-${spec.planned.id}`),
255
- at: args.createdAt,
260
+ at: args.run.createdAt,
256
261
  level: "error",
257
262
  type: "cua-lab.session.error",
258
263
  message: `Participant ${spec.planned.id}: ${outcome.sessionError}`,
@@ -261,23 +266,23 @@ function fanoutOutcomeEvents(ctx, spec, view) {
261
266
  else {
262
267
  record({
263
268
  id: nextEventId(`contract-${spec.planned.id}`),
264
- at: args.createdAt,
269
+ at: args.run.createdAt,
265
270
  level: "info",
266
271
  type: "cua-lab.contract.ready",
267
- message: `Participant ${spec.planned.id}: dry-run contract participant ready; switch scenario.mode to live for a real desktop session.`,
272
+ message: `Participant ${spec.planned.id}: dry-run participant ready; switch scenario.mode to live for a real desktop session.`,
268
273
  });
269
274
  }
270
275
  for (const warning of desktopGeometry.warnings ?? []) {
271
276
  record({
272
277
  id: nextEventId(`geometry-warning-${spec.planned.id}`),
273
- at: args.createdAt,
278
+ at: args.run.createdAt,
274
279
  level: "warn",
275
280
  type: "cua-lab.geometry.warning",
276
281
  message: warning,
277
282
  });
278
283
  }
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).
284
+ // Persisted per-participant phase trail (real boot timing): one RunEvent per completed phase
285
+ // boundary this participant recorded (started events never persist here; they carry no durationMs).
281
286
  for (const phase of outcome?.phaseRecords ?? []) {
282
287
  record({
283
288
  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: 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;