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
@@ -1,12 +1,12 @@
1
1
  import { selfReportedBlocker } from "../../run/judge.js";
2
- // "can't" followed by a PERCEPTION verb describes what the screen showed, not an inability to
2
+ // "can't" followed by a perception verb describes what the screen showed, not an inability to
3
3
  // proceed: "the canvas truncates it so you can't even read the whole thing", "I can't tell from
4
4
  // the screen whether the rename is persisted", "so I could not read its full description". Five
5
5
  // of five completed live runs on 2026-09-01 (two on drawDB, three on the planted benchmark app)
6
6
  // were refused as "not a credible pass" on exactly these sentences, every one a defect report
7
- // written AFTER the participant reached the goal. The more precisely a participant describes a
8
- // display defect, the more likely the scan was to refuse the run — the incentive inversion #453
9
- // fixed for resolved arcs, back in a new shape. "could not complete", "could not connect",
7
+ // written after the participant reached the goal. The more precisely a participant describes a
8
+ // display defect, the more likely the scan was to refuse the run: the incentive inversion the
9
+ // resolved-arc rule fixed, back in a new shape. "could not complete", "could not connect",
10
10
  // "unable to get focus" still count: those name an inability to act.
11
11
  const PERCEPTION_AFTER_MODAL = /\b(can'?t|cannot|could ?not|couldn'?t|unable to|wasn'?t able to)\s+(even\s+|quite\s+|really\s+|fully\s+)?(read|see|tell|view|make out|verify|confirm|be sure|be certain|judge|know)\b/g;
12
12
  function hasBlockerLanguage(text) {
@@ -15,17 +15,17 @@ function hasBlockerLanguage(text) {
15
15
  /\berror[:.]/.test(text) ||
16
16
  /what would you like me to do|please tell me|need (the )?(task|credentials|instructions)/.test(text));
17
17
  }
18
- /** The friction scan (inclusive): does the narrative report ANY blocker-shaped language,
18
+ /** The friction scan (inclusive): does the narrative report any blocker-shaped language,
19
19
  * resolved or not? Feeds the participants `reportedFriction` tally and feedback candidates. */
20
- // Report-shaped language: what a participant writes when it finished AND has something to say.
20
+ // Report-shaped language: what a participant writes when it finished and has something to say.
21
21
  // Every one of the day's eleven drawDB reports (2026-09-01) opened a section "What confused me"
22
22
  // or "Accessibility defects:"; none contained a blocker word, so none became a feedback candidate
23
- // and a lane that had just replicated a keyboard-accessibility defect three times drafted "Live
24
- // study completed without a participant-reported finding". Friction is the INCLUSIVE scan; a
23
+ // and a participant that had just replicated a keyboard-accessibility defect three times drafted "Live
24
+ // study completed without a participant-reported finding". Friction is the inclusive scan; a
25
25
  // false positive here adds a candidate a person then reads, which is the cheap direction.
26
26
  const REPORTED_DEFECT_LANGUAGE = /\b(defects?|bugs?|accessibilit(y|ies)|inaccessible|not (keyboard|screen.?reader)[- ]?accessible|confus(ed|ing)|hesitat(ed|ion)|unexpected(ly)?|unclear|hard to (find|tell|see|read|reach)|no (visible )?focus|overlap(ped|ping|s)?|truncat(ed|es|ion)|cut off|did nothing|nothing happened|no effect)\b/;
27
- // The friction scan's own negations (#614). "Nothing was confusing", "no defects", "not unclear"
28
- // are what a participant writes when it has NOTHING to report, and until 2026-09-03 each of them
27
+ // The friction scan's own negations. "Nothing was confusing", "no defects", "not unclear"
28
+ // are what a participant writes when it has nothing to report, and until 2026-09-03 each of them
29
29
  // counted as reported friction and became a feedback candidate whose "actual" was a sentence
30
30
  // reporting no problem. Only the report-shaped adjectives are negatable here: "no visible focus",
31
31
  // "not keyboard-accessible" and "did nothing" are defects and stay.
@@ -80,25 +80,25 @@ function interimMessageReportsFriction(message) {
80
80
  });
81
81
  }
82
82
  /** The verdict scan (strict): like the friction scan, but resolved-arc segments are stripped
83
- * first — failure narration the participant itself reports as overcome is friction on the
84
- * road, not a blocker at the destination (#453). */
83
+ * first: failure narration the participant itself reports as overcome counts as friction and
84
+ * never as a blocker. */
85
85
  function completionReasonBlocksVerdict(reason) {
86
- // Perception phrases are stripped for the VERDICT only: "I could not read the full description"
86
+ // Perception phrases are stripped for the verdict only: "I could not read the full description"
87
87
  // is friction worth a tally count and a feedback candidate (the friction scan above keeps it),
88
88
  // and it is not a reason to refuse the pass.
89
89
  return hasBlockerLanguage(stripResolvedArcSegments(stripQuotedSpans(stripNegatedNonBlockerPhrases(reason.toLowerCase()))).replace(PERCEPTION_AFTER_MODAL, ""));
90
90
  }
91
91
  // A failure segment counts as a resolved arc when the recovery is self-reported either in the
92
- // SAME segment ("the import failed but then went through") or — the common report shape — in the
93
- // immediately FOLLOWING segment as a retry/alternative that succeeded ("my first import failed
92
+ // same segment ("the import failed but then went through") or, in the common report shape, in the
93
+ // immediately following segment as a retry/alternative that succeeded ("my first import failed
94
94
  // with a parser error. A simpler SQL import succeeded."). The lookahead demands the retry flavor
95
95
  // on purpose: unrelated praise ("Separately, the search box worked") must never launder an
96
96
  // unresolved failure. "Login failed so I gave up" has no recovery anywhere and stays a blocker.
97
- // (#453 — the run-1 false negative: a defect report after demonstrated success failed the lane,
97
+ // (Without this, a defect report after demonstrated success failed the participant:
98
98
  // an incentive inversion against exactly the participant behavior a study wants most.)
99
99
  const RESOLUTION_TERMS = /\b(succeed(?:ed|s)?|success(?:ful|fully)?|worked|works around|then worked|now works?|resolved|fixed|recovered|got it working|went through)\b/;
100
100
  const RETRY_RESOLUTION = /\b(simpler|simplified|retry(?:ing)?|retried|second (?:attempt|try)|another (?:attempt|try|approach)|different (?:approach|way|route)|instead|then|eventually|after that)\b[^.!?\n]{0,80}\b(succeed(?:ed|s)?|success(?:ful|fully)?|worked|went through|completed|passed)\b/;
101
- /** Drop sentence/bullet segments whose failure language is part of a self-reported RESOLVED arc. */
101
+ /** Drop sentence/bullet segments whose failure language is part of a self-reported resolved arc. */
102
102
  function stripResolvedArcSegments(text) {
103
103
  const segments = text.split(/(?<=[.!?])\s+|\n+/);
104
104
  return segments
@@ -112,15 +112,15 @@ function stripResolvedArcSegments(text) {
112
112
  })
113
113
  .join(" ");
114
114
  }
115
- // Negations that DESCRIBE a defect rather than deny one. Kept out of every clause drop below.
115
+ // Negations that describe a defect rather than deny one. Kept out of every clause drop below.
116
116
  const DEFECT_SHAPED_NEGATION = /\bno\s+(?:visible\s+)?focus\b|\bno\s+(?:keyboard|screen.?reader)[- ]?(?:access|path|route|way|alternative|equivalent)|\bnot\s+(?:keyboard|screen.?reader)[- ]?accessible\b|\bno\s+(?:effect|feedback|response)\b|\b(?:did|does)\s+nothing\b|\bnothing\s+happened\b/;
117
117
  function stripNegatedNonBlockerPhrases(text) {
118
118
  return (text
119
- // FIRST, before the narrower rules eat the "no blockers" and leave "encountered ... error"
119
+ // First, before the narrower rules eat the "no blockers" and leave "encountered ... error"
120
120
  // behind: "I encountered no blockers or unclear error output." refused a clean passing run on
121
121
  // 2026-09-01. A verb of encounter followed by "no" negates the whole clause, so drop the clause.
122
- // ... unless the clause names a DEFECT: "the delete control had no visible focus" is a
123
- // finding, and the verb it happens to use must not decide whether it counts (#622).
122
+ // ... unless the clause names a defect: "the delete control had no visible focus" is a
123
+ // finding, and the verb it happens to use must not decide whether it counts.
124
124
  .replace(/\b(?:encountered|hit|saw|found|met|had|got|ran into)\s+no\s+[^.!?\n]*/g, (clause) => (DEFECT_SHAPED_NEGATION.test(clause) ? clause : " "))
125
125
  .replace(/\bno\s+(?:real\s+|remaining\s+|actual\s+)?(?:blocker|blockers|blocking issue|blocking issues|error|errors|failure|failures)\s+(?:was\s+|were\s+)?(?:encountered|observed|found|hit|seen|reported|detected)\b/g, "")
126
126
  .replace(/\bwithout\s+(?:a\s+|any\s+)?(?:real\s+|remaining\s+|actual\s+)?(?:blocker|blockers|blocking issue|blocking issues|error|errors|failure|failures)\b/g, "")
@@ -134,9 +134,9 @@ function stripNegatedNonBlockerPhrases(text) {
134
134
  }
135
135
  /**
136
136
  * Remove double-quoted spans and markdown blockquote lines before the blocker scan, so a persona
137
- * that faithfully QUOTES the subject app's own copy (e.g. a banner reading "cannot be undone") is
138
- * not misread as the actor reporting its OWN blocker. Only double quotes (straight and smart) and
139
- * `>` blockquotes are stripped — never single quotes, which would mangle contractions like `can't`.
137
+ * that faithfully quotes the subject app's own copy (e.g. a banner reading "cannot be undone") is
138
+ * not misread as the actor reporting its own blocker. Only double quotes (straight and smart) and
139
+ * `>` blockquotes are stripped, never single quotes, which would mangle contractions like `can't`.
140
140
  */
141
141
  function stripQuotedSpans(text) {
142
142
  return text
@@ -148,16 +148,16 @@ function traceHasStopWhenMatch(session) {
148
148
  return session.trace.items.some((item) => item.kind === "notice" &&
149
149
  item.status === "matched" &&
150
150
  // A dwell window that ended the session (then: stop) is the same class of harness-owned,
151
- // structured completion as a matched stopWhen (#510).
151
+ // structured completion as a matched stopWhen.
152
152
  (item.title.startsWith("stopWhen matched") || item.title === "dwell window complete"));
153
153
  }
154
154
  /**
155
- * A goal_satisfied lane counts as a self-reported blocker ONLY when its final narrative contradicts
156
- * the goal AND the run's own stop predicate did NOT fire. A matched stopWhen is independent,
157
- * structured completion evidence, so it overrides a text scan of the free-form narrative — which can
158
- * otherwise trip on the subject app's OWN quoted copy (e.g. a relayed "cannot be undone" banner).
159
- * Resolved-arc segments never block the verdict (#453). Returns the offending reason, or undefined
160
- * when the lane is a clean pass. Exported for testing.
155
+ * A goal_satisfied participant counts as a self-reported blocker only when its final narrative contradicts
156
+ * the goal and the run's own stop predicate did not fire. A matched stopWhen is independent,
157
+ * structured completion evidence, so it overrides a text scan of the free-form narrative, which can
158
+ * otherwise trip on the subject app's own quoted copy (e.g. a relayed "cannot be undone" banner).
159
+ * Resolved-arc segments never block the verdict. Returns the offending reason, or undefined
160
+ * when the participant is a clean pass. Exported for testing.
161
161
  */
162
162
  export function resolveSelfReportedBlocker(session) {
163
163
  return session !== undefined && selfReportedBlocker(blockerFacts(session))
@@ -187,10 +187,10 @@ export function sessionEnding(session) {
187
187
  };
188
188
  }
189
189
  /**
190
- * Friction is independent of how a completed session ended (#657). Read the participant's
190
+ * Friction is independent of how a completed session ended. Read the participant's
191
191
  * redacted messages, including earlier reports, rather than the harness-owned reason that
192
192
  * stopWhen/dwell writes. Reasoning, observations, and notices are not participant reports.
193
- * Resolved arcs still count (#453); quoted copy and negated reports still do not. This read
193
+ * Resolved arcs still count; quoted copy and negated reports still do not. This read
194
194
  * never changes the verdict. Exported for testing.
195
195
  */
196
196
  export function resolveSelfReportedFriction(session) {
@@ -3,15 +3,15 @@ import type { CuaActorDescriptor } from "../../actors/registry.js";
3
3
  import type { LabCommsEmail, LabCommsExternal, LabConfig } from "../../lab/types.js";
4
4
  import { type RunRerunLineage } from "../../run/bundle.js";
5
5
  import { type LocalTreeArchive } from "../../subject/local-tree-archive.js";
6
- import { type ComputerUseRefusal, type CuaSubjectRoute } from "./plan.js";
6
+ import { type ComputerUseRefusal } from "./plan.js";
7
7
  import type { ComputerUsePlan } from "../../lab/plan-types.js";
8
8
  import { trackRuntimeStreams, type LiveTraceFlush } from "./live-flush.js";
9
9
  import { type CuaRunBundleBase } from "./bundle.js";
10
10
  import { projectParticipantSubjects } from "./subject-projection.js";
11
- import { type CuaActorLabErrorCode, type CuaActorLabHooks, type CuaActorLabResult, type CuaParticipantDeps, type CuaParticipantPlan, type DesktopParticipantRun, type CuaSubjectProjection, type CuaSubjectProvenanceArg, type ComputerUseRunInput, type RunCuaActorLabOptions } from "./types.js";
11
+ import { type CuaActorLabErrorCode, type CuaActorLabResult, type CuaParticipantDeps, type CuaParticipantPlan, type DesktopParticipantRun, type CuaSubjectProjection, type CuaSubjectProvenanceArg, type ComputerUseRunInput, type RunCuaActorLabOptions } from "./types.js";
12
12
  /**
13
- * The envelope of a refusal the plan left for after the cwd checks. The lane cap and in-process
14
- * fan-out refusals come after the committed personas are read, so a persona-file error still wins.
13
+ * The envelope of a refusal the plan left for after the cwd checks. The participant cap and
14
+ * in-process fan-out refusals come after the committed personas are read, so a persona-file error still wins.
15
15
  */
16
16
  export declare function refuseCuaLab(options: RunCuaActorLabOptions, refusal: ComputerUseRefusal): Promise<CuaActorLabResult>;
17
17
  export type AdmittedCuaRun = Extract<Awaited<ReturnType<typeof admitCuaRun>>, {
@@ -24,13 +24,9 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
24
24
  export interface CuaRunSetup {
25
25
  plan: ComputerUsePlan;
26
26
  input: ComputerUseRunInput;
27
- /** Read for values the plan does not carry yet, and by the compatibility hooks, which take the
28
- * whole config. Participants come from the plan. */
29
- config: LabConfig;
30
27
  /** The physical project root. */
31
28
  cwd: string;
32
29
  descriptor: CuaActorDescriptor;
33
- subjectRoute: CuaSubjectRoute;
34
30
  run: StartedRun;
35
31
  streams: ReturnType<typeof trackRuntimeStreams>;
36
32
  participantRuns: DesktopParticipantRun[];
@@ -66,7 +62,6 @@ export interface CuaParticipantsSetup {
66
62
  }
67
63
  /** What only finishCuaRun reads besides the participants' outcomes. */
68
64
  export interface CuaFinishFacts {
69
- hooks: CuaActorLabHooks;
70
65
  rerunLineage: RunRerunLineage | undefined;
71
66
  publicRepo: string | undefined;
72
67
  subjectArgs: Omit<Parameters<typeof projectParticipantSubjects>[0], "outcomes" | "dryRun">;
@@ -95,23 +90,23 @@ export declare function admitCuaRun(plan: ComputerUsePlan, input: ComputerUseRun
95
90
  config: LabConfig;
96
91
  dryRun: boolean;
97
92
  cwd: string;
98
- hooks: CuaActorLabHooks;
93
+ seams: import("../../lab/lab-deps.js").LabDeps;
99
94
  streams: {
100
- hooks: CuaActorLabHooks;
95
+ onStream: NonNullable<import("../../lab/run-lab-homes.js").RunLabHomes["onStream"]>;
101
96
  showIn: (observer: import("../../index.js").ObserverResult & {
102
97
  ok: true;
103
98
  }) => void;
104
99
  attachFinal: (observer: import("../../index.js").ObserverResult) => void;
105
100
  };
106
- env: NodeJS.ProcessEnv;
107
- subjectRoute: CuaSubjectRoute;
101
+ env: Record<string, string | undefined>;
102
+ appUrl: string;
108
103
  fail: (code: CuaActorLabErrorCode, message: string, actorLabel?: string) => CuaActorLabResult;
109
104
  refuse: (code: CuaActorLabErrorCode, message: string, actorLabel?: string | undefined) => {
110
105
  ok: false;
111
106
  result: CuaActorLabResult;
112
107
  };
113
108
  descriptor: CuaActorDescriptor;
114
- runSession: (options: import("../../actors/computer-use/actor.js").CuaActorSessionOptions) => Promise<import("../../index.js").CuaLoopResult>;
109
+ runSession: (options: import("../../actors/computer-use/actor.js").CuaActorSessionOptions) => Promise<import("../../index.js").ComputerUseLoopResult>;
115
110
  externalCommsConfig: LabCommsExternal | undefined;
116
111
  externalCommsEmail: LabCommsEmail | undefined;
117
112
  participantRuns: DesktopParticipantRun[];
@@ -123,7 +118,6 @@ export declare function admitCuaRun(plan: ComputerUsePlan, input: ComputerUseRun
123
118
  knownSecretValues: string[];
124
119
  scrubKnownValues: (text: string) => string;
125
120
  publicRepo: string | undefined;
126
- hasGithubToken: boolean;
127
121
  localTreeArchive: LocalTreeArchive | undefined;
128
122
  localTreeArchiveBuffer: ArrayBuffer | undefined;
129
123
  };
@@ -1,6 +1,6 @@
1
- // The computer-use run's setup: resolve the project and route, plan the lanes, make the live
2
- // checks that need no sandbox, pack a local tree, then start the run and build the lane deps and
3
- // bundle base that the lanes and the finish share.
1
+ // The computer-use run's setup: resolve the project and route, plan the participants, make the
2
+ // live checks that need no sandbox, pack a local tree, then start the run and build the
3
+ // participant deps and bundle base that the participants and the finish share.
4
4
  import { randomBytes } from "node:crypto";
5
5
  import { realpath } from "node:fs/promises";
6
6
  import path from "node:path";
@@ -15,14 +15,16 @@ import { emitPreflightPlan, compileParticipantPersonas, loadCuaParticipants, san
15
15
  import { makeCuaRunBudget } from "./participant-model.js";
16
16
  import { e2bRequestTimeoutMs } from "../../substrates/e2b/lifetime.js";
17
17
  import { liveCuaRejection } from "./preflight.js";
18
- import { cuaDescriptorOf, cuaSubjectRoute, cuaSubjectRouteOf, } from "./plan.js";
18
+ import { cuaDescriptorOf, declaredAppUrl, plannedAppUrl } from "./plan.js";
19
19
  import { trackRuntimeStreams } from "./live-flush.js";
20
+ import { phaseEvent, planEvent } from "../../lab/run-lab-events.js";
21
+ import { defaultSubjectPhaseSink } from "../../subject/steps.js";
20
22
  import {} from "./bundle.js";
21
23
  import { packRunLocalTree } from "./local-tree-pack.js";
22
24
  import { projectParticipantSubjects, subjectProvenanceArg } from "./subject-projection.js";
23
- import { CUA_ACTOR_LAB_SCHEMA, } from "./types.js";
25
+ import { participantSubjectEnv, } from "./types.js";
24
26
  import { labPersonaIds } from "../../lab/persona-resolve.js";
25
- import { participantDesktopOf } from "./participant-desktop.js";
27
+ import { studyResultIdentity } from "../../run/study-result.js";
26
28
  /** The physical project, bound before any caller hook runs. */
27
29
  async function bindProject(cwd) {
28
30
  // Capture the physical project before reading or invoking any caller hook. A supported
@@ -32,23 +34,21 @@ async function bindProject(cwd) {
32
34
  return prepareSelectedOutputDirectory(path.dirname(physicalCwd), physicalCwd);
33
35
  }
34
36
  /**
35
- * The envelope of a refusal the plan left for after the cwd checks. The lane cap and in-process
36
- * fan-out refusals come after the committed personas are read, so a persona-file error still wins.
37
+ * The envelope of a refusal the plan left for after the cwd checks. The participant cap and
38
+ * in-process fan-out refusals come after the committed personas are read, so a persona-file error still wins.
37
39
  */
38
40
  export async function refuseCuaLab(options, refusal) {
39
41
  const { config, dryRun } = options;
40
42
  const projectRoot = await bindProject(options.cwd);
41
- const hooks = options.hooks ?? {};
42
43
  // The committed personas are read before the refusal returns, so a persona-file error wins.
43
44
  if (refusal.stage === "after-personas")
44
45
  await compileParticipantPersonas(projectRoot, labPersonaIds(config));
45
46
  return {
46
- schema: CUA_ACTOR_LAB_SCHEMA,
47
+ ...studyResultIdentity("computer-use", config.id),
47
48
  ok: false,
48
49
  cwd: projectRoot.physicalPath,
49
- labId: config.id,
50
50
  actor: refusal.actor ?? config.actors[0]?.type ?? "",
51
- appUrl: cuaSubjectRoute(config, hooks).appUrl,
51
+ appUrl: declaredAppUrl(config),
52
52
  dryRun,
53
53
  runId: options.runId ?? "not-created",
54
54
  lanes: [],
@@ -66,16 +66,17 @@ export async function admitCuaRun(plan, input, config) {
66
66
  const { dryRun } = plan;
67
67
  const projectRoot = await bindProject(input.cwd);
68
68
  const cwd = projectRoot.physicalPath;
69
- const hooks = input.hooks ?? {};
70
- const streams = trackRuntimeStreams(hooks);
71
- const env = hooks.env ?? process.env;
72
- const subjectRoute = cuaSubjectRouteOf(plan);
73
- const { cloneRoute, localTreeRoute, inProcessRoute, appUrl, subjectRepo, subjectEnvNames } = subjectRoute;
69
+ const seams = input.deps ?? {};
70
+ const streams = trackRuntimeStreams(input.onStream);
71
+ const env = input.env ?? process.env;
72
+ const { subject, desktop } = plan.runner;
73
+ const inProcess = desktop === "in-process";
74
+ const appUrl = plannedAppUrl(subject);
75
+ const subjectEnvNames = [...participantSubjectEnv(subject)];
74
76
  const fail = (code, message, actorLabel) => ({
75
- schema: CUA_ACTOR_LAB_SCHEMA,
77
+ ...studyResultIdentity("computer-use", plan.labId),
76
78
  ok: false,
77
79
  cwd,
78
- labId: plan.labId,
79
80
  actor: actorLabel ?? plan.actor,
80
81
  appUrl,
81
82
  dryRun,
@@ -88,15 +89,29 @@ export async function admitCuaRun(plan, input, config) {
88
89
  ok: false,
89
90
  result: fail(...args),
90
91
  });
92
+ // runLab's local VM study supplies a local-target app-url lab's desktop; a direct route call or
93
+ // an in-process executor on the same lab has none. It reads the declared source, as the planner
94
+ // did: a library config the parser never saw can plan to an app-url subject from another source.
95
+ if (config.subject.source === "app-url" &&
96
+ config.execution?.target === "local" &&
97
+ input.localVm === undefined)
98
+ return refuse("HUMANISH_COMPUTER_USE_LOCAL_DESKTOP_MISSING", "An app-url lab with execution.target: local needs a local desktop. runLab starts one; a direct route call or an in-process executor does not.");
91
99
  const descriptor = cuaDescriptorOf(plan.actor);
92
- const runSession = hooks.runSession ?? descriptor.runSession;
93
- // Adopter-hosted comms plane on the app-url route (#380): humanish provisions no subject here,
94
- // so it cannot host a catch — the OPERATOR runs one, and humanish still does every other part
100
+ const baseRunSession = seams.runSession ?? descriptor.runSession;
101
+ // A local VM study's sessions abort on its signal.
102
+ const localVmSignal = input.localVm?.signal;
103
+ const runSession = localVmSignal === undefined
104
+ ? baseRunSession
105
+ : (options) => baseRunSession({ ...options, signal: localVmSignal });
106
+ // Adopter-hosted comms plane on the app-url route: humanish provisions no subject here,
107
+ // so it cannot host a catch. The operator runs one, and humanish still does every other part
95
108
  // of the funnel: tells each persona its address and inbox URL, drains the catch over HTTP after
96
- // the lanes, and writes the same digest-only evidence. Declaring `external` previously did
97
- // nothing on this route (and, per #387, on every other) while its docs said otherwise.
109
+ // the participants, and writes the same digest-only evidence. Declaring `external` previously did
110
+ // nothing on this route (or on any other) while its docs said otherwise.
98
111
  const comms = plan.residual.comms;
99
- const externalCommsConfig = !cloneRoute && !localTreeRoute && !inProcessRoute ? comms?.email?.external : undefined;
112
+ const externalCommsConfig = subject.kind !== "clone" && subject.kind !== "local-tree" && !inProcess
113
+ ? comms?.email?.external
114
+ : undefined;
100
115
  const externalCommsEmail = externalCommsConfig ? comms?.email : undefined;
101
116
  const participants = await loadCuaParticipants({ plan, cwd, projectRoot, env });
102
117
  if (!participants.ok) {
@@ -104,13 +119,13 @@ export async function admitCuaRun(plan, input, config) {
104
119
  }
105
120
  const { participantRuns, participantPlan, rerunLineage } = participants;
106
121
  const participantCount = participantRuns.length;
107
- // Pre-flight plan: BEFORE any sandbox or provider call (dry-run AND live). The hook fires for
108
- // every N (observable + testable); the stderr table prints for fan-out (N>1) so single-lane
109
- // runs stay as quiet as they always were.
122
+ // Pre-flight plan: before any sandbox or provider call (dry-run and live). onEvent gets it for
123
+ // every N; the stderr table prints for fan-out (N>1) so single-participant runs stay as quiet as they
124
+ // always were.
110
125
  if (participantCount > 1) {
111
126
  emitPreflightPlan(participantPlan, plan.labId);
112
127
  }
113
- hooks.onPreflight?.(participantPlan);
128
+ input.emit?.(planEvent(participantPlan));
114
129
  await assertPreparedSelectedOutputDirectory(projectRoot);
115
130
  // Read keys once into locals (names only; values never logged or persisted).
116
131
  const openaiApiKey = env.OPENAI_API_KEY?.trim() ?? "";
@@ -124,39 +139,35 @@ export async function admitCuaRun(plan, input, config) {
124
139
  const scrubKnownValues = scrubLiterals(knownSecretValues);
125
140
  sanitizeParticipantRuns(participantRuns, scrubKnownValues);
126
141
  const redactRepoLabel = plan.residual.policies?.redactRepos ?? subjectEnvNames.includes("GITHUB_TOKEN");
127
- const publicRepo = cloneRoute && subjectRepo ? (redactRepoLabel ? "repo-01" : subjectRepo) : undefined;
128
- const hasGithubToken = subjectEnvNames.includes("GITHUB_TOKEN");
129
- // Key-gating is route-aware: the in-process route uses the caller's OWN model + executor, and
142
+ const publicRepo = subject.kind === "clone" ? (redactRepoLabel ? "repo-01" : subject.repo) : undefined;
143
+ // Key-gating is route-aware: the in-process route uses the caller's own model + executor, and
130
144
  // the local-agent route uses a CLI the operator has already signed in to.
131
- if (!dryRun && !inProcessRoute) {
145
+ if (!dryRun && !inProcess) {
132
146
  const rejection = await liveCuaRejection({
133
147
  caps: plan.caps,
134
148
  brain: plan.runner.brain,
135
- hooks,
136
149
  env,
137
- openaiApiKey,
138
- e2bApiKey,
139
- subjectEnvNames,
150
+ requirements: plan.requirements,
140
151
  externalCommsConfig,
141
152
  });
142
153
  if (rejection)
143
154
  return refuse(rejection.code, rejection.message, descriptor.id);
144
155
  }
145
- // Pack the working tree ONCE per run, on the host, BEFORE any sandbox or provider call: every
146
- // fan-out lane below uploads this SAME archive, so one archiveSha256 describes every lane's
147
- // digest. Dry-run packs nothing (no fs side effects; the contract bundle carries no
156
+ // Pack the working tree once per run, on the host, before any sandbox or provider call: every
157
+ // fan-out participant below uploads this same archive, so one archiveSha256 describes every
158
+ // participant's digest. Dry-run packs nothing (no fs side effects; the contract bundle carries no
148
159
  // archiveSha256). A packing failure fails the run closed here, before any sandbox is
149
160
  // created and before the run directory exists.
150
161
  let localTreeArchive;
151
162
  let localTreeArchiveBuffer;
152
- if (localTreeRoute && !dryRun) {
163
+ if (subject.kind === "local-tree" && !dryRun) {
153
164
  try {
154
- const packed = await packRunLocalTree(hooks, plan.residual, cwd);
165
+ const packed = await packRunLocalTree(seams, plan.residual, cwd);
155
166
  localTreeArchive = packed.archive;
156
167
  localTreeArchiveBuffer = packed.buffer;
157
168
  }
158
169
  catch (error) {
159
- return refuse("HUMANISH_CUA_LAB_SUBJECT_INVALID", `local-tree packing failed: ${redactText(scrubKnownValues(toErrorMessage(error)))}`, descriptor.id);
170
+ return refuse("HUMANISH_COMPUTER_USE_SUBJECT_INVALID", `local-tree packing failed: ${redactText(scrubKnownValues(toErrorMessage(error)))}`, descriptor.id);
160
171
  }
161
172
  }
162
173
  return {
@@ -165,10 +176,10 @@ export async function admitCuaRun(plan, input, config) {
165
176
  config,
166
177
  dryRun,
167
178
  cwd,
168
- hooks,
179
+ seams,
169
180
  streams,
170
181
  env,
171
- subjectRoute,
182
+ appUrl,
172
183
  fail,
173
184
  refuse,
174
185
  descriptor,
@@ -184,7 +195,6 @@ export async function admitCuaRun(plan, input, config) {
184
195
  knownSecretValues,
185
196
  scrubKnownValues,
186
197
  publicRepo,
187
- hasGithubToken,
188
198
  localTreeArchive,
189
199
  localTreeArchiveBuffer,
190
200
  },
@@ -192,8 +202,8 @@ export async function admitCuaRun(plan, input, config) {
192
202
  }
193
203
  /** Starts the run and builds what the participants and the finish read: the deps and the bundle base. */
194
204
  export async function startCuaRun(plan, input, admitted, scope) {
195
- const { config, dryRun, cwd, hooks, descriptor, participantRuns, participantPlan, publicRepo } = admitted;
196
- const { appUrl, inProcessRoute, localAppSubject, cloneRoute, localTreeRoute, subjectEnvNames } = admitted.subjectRoute;
205
+ const { dryRun, cwd, seams, descriptor, participantRuns, participantPlan, publicRepo } = admitted;
206
+ const { appUrl } = admitted;
197
207
  // The run's status record exists from here on, so anything watching the runs directory can
198
208
  // tell which lab this is and that it is alive. The fail-closed returns below leave it finished
199
209
  // with no outcome when the scope closes; a crash leaves it stale, which reads as interrupted.
@@ -204,12 +214,12 @@ export async function startCuaRun(plan, input, admitted, scope) {
204
214
  mode: dryRun ? "dry-run" : "live",
205
215
  lab: plan.lab,
206
216
  renderReview: renderCuaReviewMarkdown,
207
- observer: { open: input.open === true, render: hooks.renderObserverFn },
217
+ observer: { open: input.open === true, render: seams.renderObserver },
208
218
  });
209
219
  if (!started.ok)
210
220
  return admitted.refuse(started.code, started.message, descriptor.id);
211
221
  const { run } = started;
212
- const { runId, createdAt, paths: runPaths } = run;
222
+ const { createdAt, paths: runPaths } = run;
213
223
  const redactScreenshots = plan.residual.policies?.redactScreenshots === true;
214
224
  await prepareContainedOutputDirectory(runPaths, "screenshots");
215
225
  const source = await buildRunSource({
@@ -218,8 +228,8 @@ export async function startCuaRun(plan, input, admitted, scope) {
218
228
  humanishSource: "present",
219
229
  packageName: "humanish",
220
230
  });
221
- // Live-trace flush seam (#441): runLabParticipants fills it when a live run has an in-progress bundle
222
- // to grow; lanes call it through deps.onTrace. It exists before deps so deps can reference it as
231
+ // Live-trace flush seam: runLabParticipants fills it when a live run has an in-progress bundle
232
+ // to grow; participants call it through deps.onTrace. It exists before deps so deps can reference it as
223
233
  // a stable indirection.
224
234
  const liveTrace = {};
225
235
  const deps = cuaParticipantDeps(plan, input, admitted, {
@@ -229,7 +239,6 @@ export async function startCuaRun(plan, input, admitted, scope) {
229
239
  });
230
240
  const subjectArgs = {
231
241
  plan,
232
- subjectRoute: admitted.subjectRoute,
233
242
  ...(publicRepo === undefined ? {} : { publicRepo }),
234
243
  ...(admitted.localTreeArchive === undefined
235
244
  ? {}
@@ -242,25 +251,20 @@ export async function startCuaRun(plan, input, admitted, scope) {
242
251
  dryRun: false,
243
252
  });
244
253
  const inProgressAggregateSubject = inProgressSubjects[0];
245
- const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo, subjectEnvNames);
254
+ const inProgressProvenance = subjectProvenanceArg(inProgressAggregateSubject, publicRepo, [
255
+ ...participantSubjectEnv(plan.runner.subject),
256
+ ]);
246
257
  const bundleBase = {
247
- ...(plan.lab === undefined ? {} : { lab: plan.lab }),
258
+ run,
248
259
  participantRuns,
249
260
  descriptor,
250
261
  appUrl,
251
- createdAt,
252
262
  plan,
253
- runId,
254
263
  source,
255
264
  participantPlan,
256
265
  ...(admitted.rerunLineage === undefined ? {} : { rerun: admitted.rerunLineage }),
257
266
  redactScreenshots,
258
- inProcessRoute,
259
- localAppSubject,
260
- cloneRoute,
261
- localTreeRoute,
262
267
  ...(publicRepo === undefined ? {} : { publicRepo }),
263
- subjectEnvNames,
264
268
  };
265
269
  const { externalCommsConfig, externalCommsEmail } = admitted;
266
270
  return {
@@ -268,10 +272,8 @@ export async function startCuaRun(plan, input, admitted, scope) {
268
272
  setup: {
269
273
  plan,
270
274
  input,
271
- config,
272
275
  cwd,
273
276
  descriptor,
274
- subjectRoute: admitted.subjectRoute,
275
277
  run,
276
278
  streams: admitted.streams,
277
279
  participantRuns,
@@ -294,35 +296,30 @@ export async function startCuaRun(plan, input, admitted, scope) {
294
296
  },
295
297
  fail: admitted.fail,
296
298
  },
297
- finish: { hooks, rerunLineage: admitted.rerunLineage, publicRepo, subjectArgs },
299
+ finish: { rerunLineage: admitted.rerunLineage, publicRepo, subjectArgs },
298
300
  };
299
301
  }
300
- /** The lane deps every lane reads: the route, keys, timeouts, scrubber, budget and hooks. */
302
+ /** The participant deps every participant reads: the route, keys, timeouts, scrubber, budget and seams. */
301
303
  function cuaParticipantDeps(plan, input, admitted, run) {
302
- const { config, dryRun, hooks, streams, env, descriptor, runSession, participantCount } = admitted;
303
- const { hasGithubToken, localTreeArchiveBuffer } = admitted;
304
+ const { config, dryRun, seams, streams, env, runSession, participantCount } = admitted;
305
+ const { localTreeArchiveBuffer } = admitted;
304
306
  const { openaiApiKey, e2bApiKey, scrubKnownValues } = admitted;
305
307
  const { externalCommsConfig, externalCommsEmail } = admitted;
306
- const { appUrl, cloneRoute, desktopCliRoute, localTreeRoute, serve, subjectRepo } = admitted.subjectRoute;
307
- const { subjectEnvNames } = admitted.subjectRoute;
308
+ const { appUrl } = admitted;
308
309
  const { runPaths, redactScreenshots, liveTrace } = run;
309
- const createDesktop = participantDesktopOf(hooks);
310
+ const createDesktop = input.localVm?.desktop;
310
311
  const timeoutMs = plan.sessionBudgetMs;
311
312
  const requestTimeoutMs = e2bRequestTimeoutMs(env);
312
313
  return {
313
314
  ...(createDesktop === undefined ? {} : { createDesktop }),
314
315
  onTrace: (participantId, items, usage, metadata) => liveTrace.flush?.(participantId, items, usage, metadata),
315
- config,
316
- descriptor,
316
+ ...callerDriving(input, config),
317
+ residual: plan.residual,
318
+ labId: plan.labId,
319
+ caps: plan.caps,
317
320
  appUrl,
318
321
  brain: plan.runner.brain,
319
- cloneRoute,
320
- desktopCliRoute,
321
- localTreeRoute,
322
- ...(serve === undefined ? {} : { serve }),
323
- ...(subjectRepo === undefined ? {} : { subjectRepo }),
324
- subjectEnvNames,
325
- hasGithubToken,
322
+ subject: plan.runner.subject,
326
323
  ...(localTreeArchiveBuffer === undefined ? {} : { localTreeArchiveBuffer }),
327
324
  env,
328
325
  openaiApiKey,
@@ -336,7 +333,7 @@ function cuaParticipantDeps(plan, input, admitted, run) {
336
333
  redactScreenshots,
337
334
  scrubKnownValues,
338
335
  runSession,
339
- // The study-level ledger exists once per RUN, shared by every lane (#299). Dry runs never
336
+ // The study-level ledger exists once per run, shared by every participant. Dry runs never
340
337
  // spend, so they carry none.
341
338
  ...(dryRun || plan.caps.maxTotalUsd === undefined
342
339
  ? {}
@@ -349,8 +346,34 @@ function cuaParticipantDeps(plan, input, admitted, run) {
349
346
  inboxUrl: externalInboxUrl(externalCommsConfig),
350
347
  },
351
348
  }),
352
- now: hooks.now ?? Date.now,
353
- hooks: streams.hooks,
349
+ now: seams.now ?? Date.now,
350
+ ...(seams.desktopModule === undefined ? {} : { desktopModule: seams.desktopModule }),
351
+ ...(input.prepareDesktop === undefined ? {} : { prepareDesktop: input.prepareDesktop }),
352
+ ...(seams.detachedTimers === undefined ? {} : { detachedTimers: seams.detachedTimers }),
353
+ onStream: streams.onStream,
354
+ reportSubjectPhase: subjectPhaseReporter(input),
355
+ };
356
+ }
357
+ /** The caller's createProvider and inProcess executor, with the run's config bound. */
358
+ function callerDriving(input, config) {
359
+ const { createProvider, inProcess } = input;
360
+ return {
361
+ ...(createProvider === undefined
362
+ ? {}
363
+ : {
364
+ createProvider: (participant, executor) => createProvider({ config, participant, executor }),
365
+ }),
366
+ ...(inProcess === undefined
367
+ ? {}
368
+ : { inProcessExecutor: (appUrl) => inProcess.executor({ config, appUrl }) }),
369
+ };
370
+ }
371
+ /** Each subject phase goes to the phase sink, stderr by default, and to onEvent. */
372
+ function subjectPhaseReporter(input) {
373
+ const sink = input.deps?.subjectPhaseSink ?? defaultSubjectPhaseSink;
374
+ return (event, participant) => {
375
+ sink(event, participant);
376
+ input.emit?.(phaseEvent(event, { kind: "participant", participant }));
354
377
  };
355
378
  }
356
379
  function makeCuaRunId() {