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,16 +1,17 @@
1
1
  import { pricedModel } from "../../lab/plan-base.js";
2
+ import { missingKeys, missingSubjectEnv } from "../../lab/requirements.js";
2
3
  import { detectLocalAgents } from "../../actors/local-agent/cli.js";
3
4
  import { localAgentRefusal } from "../../actors/local-agent/readiness.js";
4
5
  import { describeMissingKeys } from "../../keys/key-resolution.js";
6
+ import { catchTokenOf, catchTokenRefusal } from "../../comms/external-evidence.js";
5
7
  import { externalCatchHealthy } from "../../comms/sandbox-catch.js";
6
- import { MODEL_RATES } from "../../run/pricing.js";
7
- import { participantDesktopOf } from "./participant-desktop.js";
8
+ import { MODEL_RATES, unpricedCapMessage } from "../../run/pricing.js";
8
9
  /** The computer-use code for each local-agent refusal; shared-world keeps the same kinds. */
9
10
  const LOCAL_AGENT_REFUSAL_CODES = {
10
- "agent-missing": "HUMANISH_CUA_LAB_AGENT_MISSING",
11
- "signin-required": "HUMANISH_CUA_LAB_AGENT_SIGNIN_REQUIRED",
12
- unsupported: "HUMANISH_CUA_LAB_ACTOR_UNSUPPORTED",
13
- "unpriced-cap": "HUMANISH_CUA_LAB_UNPRICED_CAP",
11
+ "agent-missing": "HUMANISH_COMPUTER_USE_AGENT_MISSING",
12
+ "signin-required": "HUMANISH_COMPUTER_USE_AGENT_SIGNIN_REQUIRED",
13
+ unsupported: "HUMANISH_COMPUTER_USE_ACTOR_UNSUPPORTED",
14
+ "unpriced-cap": "HUMANISH_COMPUTER_USE_UNPRICED_CAP",
14
15
  };
15
16
  /**
16
17
  * The first reason a live computer-use run cannot start on this machine: missing keys, a missing
@@ -19,69 +20,72 @@ const LOCAL_AGENT_REFUSAL_CODES = {
19
20
  * already paid for a desktop.
20
21
  */
21
22
  export async function liveCuaRejection(args) {
22
- const { caps, brain, hooks, env, openaiApiKey, e2bApiKey, subjectEnvNames, externalCommsConfig } = args;
23
- // The operator's own signed-in coding agent is the brain, so there is no provider key to ask
24
- // for. E2B is still required: the persona needs a machine.
23
+ const { caps, brain, env, requirements, externalCommsConfig } = args;
24
+ // The plan lists OPENAI_API_KEY only for an openai brain (a signed-in local agent or the
25
+ // caller's provider needs none) and E2B_API_KEY only when this run creates hosted desktops.
25
26
  const localAgent = brain.kind === "local-agent" ? brain.agent : undefined;
26
- const missingKeys = [
27
- ...(openaiApiKey || localAgent || hooks.buildProvider ? [] : ["OPENAI_API_KEY"]),
28
- ...(e2bApiKey || participantDesktopOf(hooks) !== undefined ? [] : ["E2B_API_KEY"]),
29
- ];
30
- if (missingKeys.length > 0) {
27
+ const missing = missingKeys(requirements, env);
28
+ if (missing.length > 0) {
31
29
  // The moment someone new actually hits the wall. If a signed-in coding agent is sitting
32
- // right there, say so HERE rather than making them go and find an API key — that detour is
30
+ // right there, say so here rather than making them go and find an API key; that detour is
33
31
  // where most people trying humanish stop.
34
- const suggestion = missingKeys.includes("OPENAI_API_KEY")
32
+ const suggestion = missing.includes("OPENAI_API_KEY")
35
33
  ? await (async () => {
36
34
  const ready = (await detectLocalAgents({ env })).filter((agent) => agent.authStatus === "authenticated");
37
35
  return ready.length === 0
38
36
  ? ""
39
37
  : ` ${ready.map((agent) => agent.label).join(" and ")} reports authenticated on this machine` +
40
- ` — set actors[0].type: local-agent to use ${ready.length === 1 ? "it" : "one"} instead of a key.`;
38
+ `. Set actors[0].type: local-agent to use ${ready.length === 1 ? "it" : "one"} instead of a key.`;
41
39
  })()
42
40
  : "";
43
41
  return {
44
- code: "HUMANISH_CUA_LAB_KEYS_MISSING",
45
- message: `Live computer-use labs need ${missingKeys.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missingKeys, env)}${suggestion}`,
42
+ code: "HUMANISH_COMPUTER_USE_KEYS_MISSING",
43
+ message: `Live computer-use labs need ${missing.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missing, env)}${suggestion}`,
46
44
  };
47
45
  }
48
- if (localAgent && !hooks.buildProvider) {
49
- // Refuse HERE, before a sandbox exists. "codex is not installed" discovered after the
46
+ // A caller's createProvider makes the brain `caller`, so only the lab's own local agent is checked.
47
+ if (localAgent) {
48
+ // Refuse here, before a sandbox exists. "codex is not installed" discovered after the
50
49
  // machine is paid for is the same information delivered at the worst possible moment.
51
50
  const refusal = await localAgentRefusal({ agent: localAgent, env, caps });
52
51
  if (refusal)
53
52
  return { code: LOCAL_AGENT_REFUSAL_CODES[refusal.kind], message: refusal.message };
54
53
  }
55
- const missingSubjectEnv = subjectEnvNames.filter((name) => !env[name]?.trim());
56
- if (missingSubjectEnv.length > 0) {
54
+ const unsetSubjectEnv = missingSubjectEnv(requirements, env);
55
+ if (unsetSubjectEnv.length > 0) {
57
56
  return {
58
- code: "HUMANISH_CUA_LAB_SUBJECT_ENV_MISSING",
59
- message: `subject.env declares ${missingSubjectEnv.join(", ")} but the environment does not provide ${missingSubjectEnv.length === 1 ? "it" : "them"} (pass via --env-file; values are never persisted).`,
57
+ code: "HUMANISH_COMPUTER_USE_SUBJECT_ENV_MISSING",
58
+ message: `subject.env declares ${unsetSubjectEnv.join(", ")} but the environment does not provide ${unsetSubjectEnv.length === 1 ? "it" : "them"} (pass via --env-file; values are never persisted).`,
60
59
  };
61
60
  }
62
- // FAIL-CLOSED CAP TENSION (discipline #3): a maxUsd cap needs a MEASURABLE per-turn estimate.
61
+ // Fail-closed cap: a maxUsd cap needs a measurable per-turn estimate.
63
62
  // If the operator set execution.caps.maxUsd but src/run/pricing.ts has no rate for the resolved
64
- // model, the loop could not enforce the cap — and silently running uncapped would break the
65
- // runaway-retry protection. Refuse at PREFLIGHT (before any sandbox/spend) rather than run
66
- // uncapped: an unenforceable cap is more dangerous than none. The operator adds a rate to
67
- // src/run/pricing.ts (the honest place) or removes the cap.
63
+ // model, the loop could not enforce the cap, and silently running uncapped would break the
64
+ // runaway-retry protection. Refuse at preflight (before any sandbox/spend) rather than run
65
+ // uncapped: an unenforceable cap is more dangerous than none. The operator picks a priced model
66
+ // or removes the cap; a source checkout can also add a rate to src/run/pricing.ts.
68
67
  if (caps.maxUsd !== undefined || caps.maxTotalUsd !== undefined) {
69
68
  const model = pricedModel(brain);
70
69
  const capModelId = model.trim().toLowerCase();
71
70
  if (!MODEL_RATES[capModelId]) {
72
71
  return {
73
- code: "HUMANISH_CUA_LAB_UNPRICED_CAP",
74
- message: `execution.caps declares a spend cap (maxUsd/maxTotalUsd) but src/run/pricing.ts has no rate for model "${model}"; add a rate or remove the cap — an unenforceable cap is refused rather than run uncapped.`,
72
+ code: "HUMANISH_COMPUTER_USE_UNPRICED_CAP",
73
+ message: unpricedCapMessage(model),
75
74
  };
76
75
  }
77
76
  }
78
- // Adopter-hosted comms catch (#380): fail closed BEFORE any sandbox is created — a comms lab
79
- // whose catch is unreachable collects nothing while every lane still spends. The probe asserts
80
- // OUR service marker in /health, so an adopter's proxy answering 200 for everything cannot
77
+ // Adopter-hosted comms catch: fail closed before any sandbox is created, because a comms lab
78
+ // whose catch is unreachable collects nothing while every participant still spends. The probe asserts
79
+ // humanish's own service marker in /health, so an adopter's proxy answering 200 for everything cannot
81
80
  // pass for a catch.
81
+ const tokenRefusal = externalCommsConfig === undefined
82
+ ? undefined
83
+ : catchTokenRefusal(catchTokenOf(externalCommsConfig, env));
84
+ if (tokenRefusal !== undefined)
85
+ return { code: "HUMANISH_COMPUTER_USE_COMMS_TOKEN_INVALID", message: tokenRefusal };
82
86
  if (externalCommsConfig && !(await externalCatchHealthy(externalCommsConfig))) {
83
87
  return {
84
- code: "HUMANISH_CUA_LAB_COMMS_CATCH_UNREACHABLE",
88
+ code: "HUMANISH_COMPUTER_USE_COMMS_CATCH_UNREACHABLE",
85
89
  message: "The external comms catch or inbox is unreachable or incompatible (GET /health must identify humanish-comms-catch and advertise recipient-inbox-v1). Update humanish on the catch host and restart it with `humanish comms catch` on that host, or drop comms.email to run without the inbox funnel.",
86
90
  };
87
91
  }
@@ -36,7 +36,7 @@ export async function resolveCuaRerunSelection(args) {
36
36
  if (selectedIds.length === 0) {
37
37
  return {
38
38
  ok: false,
39
- message: `source run ${bundle.runId} has no failed, blocked, timed-out, or hollow participants to rerun.`,
39
+ message: `source run ${bundle.runId} has no participant to rerun: none failed, was blocked, timed out or ended without engaging.`,
40
40
  };
41
41
  }
42
42
  const missingPrior = selectedIds.filter((id) => !priorById.has(id));
@@ -99,13 +99,17 @@ function snapshotPriorParticipant(stream) {
99
99
  const reason = stream.ui?.state ?? stream.actor?.reason;
100
100
  const actions = stream.actor?.counts.actions ?? 0;
101
101
  const messages = stream.actor?.counts.messages ?? 0;
102
+ // The judge's status decides, so a participant the review counts as blocked is rerunnable. A
103
+ // bundle written before streams carried it falls back to the trace status and counts.
102
104
  const hollow = completionReason === "goal_satisfied" && actions === 0 && messages === 0;
103
- const rerunnable = stream.status !== "passed" ||
104
- actorStatus === "failed" ||
105
- actorStatus === "blocked" ||
106
- actorStatus === "timed_out" ||
107
- completionReason === "harness_error" ||
108
- hollow;
105
+ const rerunnable = stream.judgedStatus !== undefined
106
+ ? stream.judgedStatus !== "passed"
107
+ : stream.status !== "passed" ||
108
+ actorStatus === "failed" ||
109
+ actorStatus === "blocked" ||
110
+ actorStatus === "timed_out" ||
111
+ completionReason === "harness_error" ||
112
+ hollow;
109
113
  return {
110
114
  participantId: stream.laneId,
111
115
  previous: {
@@ -1,4 +1,4 @@
1
- import type { runLabParticipants } from "./run-lanes.js";
1
+ import type { runLabParticipants } from "./live-phase.js";
2
2
  import type { CuaFinishFacts, CuaRunSetup } from "./setup.js";
3
3
  import { type CuaActorLabResult } from "./types.js";
4
4
  /** Builds and publishes the final bundle, runs the adapter hooks, renders the Observer and returns the result. */
@@ -1,13 +1,15 @@
1
- import { adapterScoreFailureMessage, applyBrowserAdapterHooks, } from "../../lab/adapter-extension.js";
1
+ import { adapterScoreFailureMessage, applyBrowserScorer } from "../../lab/adapter-extension.js";
2
2
  import { redactText } from "../../evidence/redaction.js";
3
3
  import { round6 } from "../../run/pricing.js";
4
4
  import { foldScorerFailures, judgeExecution, OUTCOME_POLICIES, participantHarnessFailed, resultOk, } from "../../run/judge.js";
5
- import { participantFactsOf, participantOutcomeOk } from "./participant-facts.js";
5
+ import { participantFactsOf, participantOutcomeOk, unreleasedSandboxFailures, } from "./participant-facts.js";
6
6
  import { summarizeCuaDiagnostics } from "./diagnostics.js";
7
- import { toParticipantResult } from "./lanes.js";
7
+ import { toParticipantResult } from "./participant-execution.js";
8
8
  import { buildCuaRunBundle, judgeComputerUseRun } from "./bundle.js";
9
9
  import { aggregateCuaSubject, projectParticipantSubjects, subjectProvenanceArg, } from "./subject-projection.js";
10
- import { CUA_ACTOR_LAB_SCHEMA, CUA_FANOUT_STRATEGY, } from "./types.js";
10
+ import { CUA_FANOUT_STRATEGY, participantSubjectEnv, } from "./types.js";
11
+ import { plannedAppUrl } from "./plan.js";
12
+ import { studyResultIdentity } from "../../run/study-result.js";
11
13
  /** Aggregate participant counts for the result projection. */
12
14
  function buildParticipantSummary(outcomes, participantCount, participantPlan, dryRun) {
13
15
  if (dryRun || !outcomes) {
@@ -51,13 +53,14 @@ function buildParticipantSummary(outcomes, participantCount, participantPlan, dr
51
53
  }
52
54
  /**
53
55
  * The computer-use lab result for a finished run. The run passes only when the Observer rendered,
54
- * every lane passed (dry-run lanes pass as contracts), and no adapter score or declared scorer
56
+ * every participant passed (dry-run participants pass as contracts), and no adapter score or declared scorer
55
57
  * verdict failed; otherwise the error names the first reason.
56
58
  */
57
59
  function cuaLabResult(args) {
58
60
  const { labId, cwd, runId, appUrl, dryRun, participantRuns, outcomes, subjects, aggregateSubject, participantPlan, rerunLineage, bundle, observer, receivingWarnings, aggregateWarnings, adapterWarnings, } = args;
59
61
  const participantCount = participantRuns.length;
60
- // Lane-level pass: dry-run lanes are contract-ok; live lanes need a passed, engaged session.
62
+ // Participant-level pass: dry-run participants are contract-ok; live ones need a passed,
63
+ // engaged session.
61
64
  const participantOk = (outcome) => participantOutcomeOk(outcome, dryRun);
62
65
  const adapterFailure = adapterScoreFailureMessage(bundle);
63
66
  const ok = resultOk({
@@ -81,21 +84,19 @@ function cuaLabResult(args) {
81
84
  if (ok)
82
85
  return undefined;
83
86
  if (adapterFailure !== undefined) {
84
- return {
85
- code: "HUMANISH_CUA_LAB_FAILED",
86
- message: adapterFailure,
87
- };
87
+ return { code: "HUMANISH_COMPUTER_USE_FAILED", message: adapterFailure };
88
88
  }
89
89
  if (participantCount === 1) {
90
90
  const outcome = firstOutcome;
91
91
  return {
92
- code: outcome?.failureCode ?? "HUMANISH_CUA_LAB_FAILED",
92
+ code: outcome?.failureCode ?? "HUMANISH_COMPUTER_USE_FAILED",
93
93
  message: outcome?.sessionError ??
94
94
  outcome?.providerCleanupError ??
95
+ outcome?.providerPolicyError ??
95
96
  (outcome?.noEngagement
96
97
  ? "Actor took no actions and produced no message (likely a blank/still-loading screen); not a credible goal_satisfied."
97
- : // The lane result (toParticipantResult) named this refusal; the N=1 envelope fell through to
98
- // "did not produce a terminal session", which is false — it produced one and refused it.
98
+ : // The participant result (toParticipantResult) named this refusal; the N=1 envelope fell through to
99
+ // "did not produce a terminal session", which is false: it produced one and refused it.
99
100
  outcome?.selfReportedBlocker
100
101
  ? "Actor reported goal_satisfied while its final message described a blocker or asked for missing instructions; not a credible pass."
101
102
  : observer.ok
@@ -108,20 +109,19 @@ function cuaLabResult(args) {
108
109
  };
109
110
  }
110
111
  const failing = (outcomes ?? []).find((outcome) => !participantOk(outcome));
111
- const geometryFailure = (outcomes ?? []).find((outcome) => outcome.failureCode === "HUMANISH_CUA_LAB_DEVICE_GEOMETRY");
112
- const code = geometryFailure?.failureCode ?? "HUMANISH_CUA_LAB_FAILED";
112
+ const geometryFailure = (outcomes ?? []).find((outcome) => outcome.failureCode === "HUMANISH_COMPUTER_USE_DEVICE_GEOMETRY");
113
+ const code = geometryFailure?.failureCode ?? "HUMANISH_COMPUTER_USE_FAILED";
113
114
  return {
114
115
  code,
115
116
  message: observer.ok
116
- ? `Fan-out run failed: ${summary.passed}/${participantCount} participant(s) passed (${summary.skipped} skipped, ${summary.harnessErrors} harness error(s), ${summary.hollow} hollow)${failing?.sessionError !== undefined ? `; first failure: ${failing.sessionError}` : failing === undefined && args.execution.failures[0] !== undefined ? `; ${args.execution.failures[0].message}` : ""}.`
117
+ ? `Fan-out run failed: ${summary.passed}/${participantCount} participant(s) passed (${summary.skipped} skipped, ${summary.harnessErrors} harness error(s), ${summary.hollow} without engagement)${failing?.sessionError !== undefined ? `; first failure: ${failing.sessionError}` : failing === undefined && args.execution.failures[0] !== undefined ? `; ${args.execution.failures[0].message}` : ""}.`
117
118
  : (observer.error?.message ?? "Observer failed for the computer-use fan-out run."),
118
119
  };
119
120
  })();
120
121
  return {
121
- schema: CUA_ACTOR_LAB_SCHEMA,
122
+ ...studyResultIdentity("computer-use", labId),
122
123
  ok,
123
124
  cwd,
124
- labId,
125
125
  actor: args.actorId,
126
126
  appUrl,
127
127
  dryRun,
@@ -164,10 +164,11 @@ function cuaLabResult(args) {
164
164
  };
165
165
  }
166
166
  /**
167
- * The run's execution failures: each lane whose session failed in the harness, and an Observer
168
- * that failed.
167
+ * The run's execution failures: each participant whose session failed in the harness, each provider whose
168
+ * cleanup is unconfirmed or that reported a disallowed item after its last request, each sandbox
169
+ * whose release is unconfirmed, and an Observer that failed.
169
170
  */
170
- function computerUseExecutionFailures(outcomes, observer) {
171
+ function computerUseExecutionFailures(outcomes, observer, runId) {
171
172
  return [
172
173
  ...(outcomes ?? [])
173
174
  .filter((outcome) => participantHarnessFailed(participantFactsOf(outcome)))
@@ -183,6 +184,15 @@ function computerUseExecutionFailures(outcomes, observer) {
183
184
  message: `${outcome.spec.planned.id}: ${outcome.providerCleanupError}`,
184
185
  },
185
186
  ]),
187
+ ...(outcomes ?? []).flatMap((outcome) => outcome.providerPolicyError === undefined
188
+ ? []
189
+ : [
190
+ {
191
+ kind: "provider-policy",
192
+ message: `${outcome.spec.planned.id}: ${outcome.providerPolicyError}`,
193
+ },
194
+ ]),
195
+ ...unreleasedSandboxFailures(outcomes, runId),
186
196
  ...(observer.ok
187
197
  ? []
188
198
  : [
@@ -194,33 +204,34 @@ function computerUseExecutionFailures(outcomes, observer) {
194
204
  ];
195
205
  }
196
206
  /**
197
- * execution.caps.maxUsd is enforced inside each lane's loop independently, so an N-lane fan-out can
198
- * spend up to N × maxUsd before any lane aborts, while the run cost summary reports the larger
207
+ * execution.caps.maxUsd is enforced inside each participant's loop independently, so an
208
+ * N-participant fan-out can spend up to N × maxUsd before any participant aborts, while the run cost summary reports the larger
199
209
  * aggregate. The warning names that ceiling, unless the study declared a shared maxTotalUsd budget.
200
210
  */
201
- function participantCapWarning(config, participantCount) {
202
- const capUsd = config.execution?.caps?.maxUsd;
211
+ function participantCapWarning(caps, participantCount) {
212
+ const capUsd = caps.maxUsd;
203
213
  if (capUsd === undefined || participantCount <= 1)
204
214
  return undefined;
205
- if (config.execution?.caps?.maxTotalUsd !== undefined)
215
+ if (caps.maxTotalUsd !== undefined)
206
216
  return undefined;
207
- return `execution.caps.maxUsd ($${capUsd}) is a PER-PARTICIPANT cap; ${participantCount} participants may spend up to ${participantCount} × $${capUsd} (~$${round6(capUsd * participantCount)} total) before any participant aborts. Set execution.caps.maxTotalUsd for a shared study budget.`;
217
+ return `execution.caps.maxUsd ($${capUsd}) caps each participant, so ${participantCount} participants may spend up to ${participantCount} × $${capUsd} (about $${round6(capUsd * participantCount)}) before any of them stops. Set execution.caps.maxTotalUsd for one budget across the study.`;
208
218
  }
209
219
  /** Builds and publishes the final bundle, runs the adapter hooks, renders the Observer and returns the result. */
210
220
  export async function finishCuaRun(setup, finish, ran) {
211
- const { plan, input, config, cwd, streams, descriptor, subjectRoute, run } = setup;
221
+ const { plan, input, cwd, streams, descriptor, run } = setup;
212
222
  const { participantRuns, participantPlan, scrubKnownValues, bundleBase } = setup;
213
- const { hooks, rerunLineage, publicRepo, subjectArgs } = finish;
223
+ const { rerunLineage, publicRepo, subjectArgs } = finish;
214
224
  const { dryRun } = plan;
215
- const { appUrl, subjectEnvNames } = subjectRoute;
225
+ const appUrl = plannedAppUrl(plan.runner.subject);
226
+ const subjectEnvNames = [...participantSubjectEnv(plan.runner.subject)];
216
227
  const { runId } = run;
217
228
  const participantCount = participantRuns.length;
218
229
  const { outcomes, failFastReason, receiving, receivingWarnings, externalCommsWarnings } = ran;
219
- // Per-lane subject projections (invariant 5).
230
+ // Per-participant subject projections.
220
231
  const subjects = projectParticipantSubjects({ ...subjectArgs, outcomes, dryRun });
221
232
  const aggregate = aggregateCuaSubject({ subjects, outcomes, participantCount, dryRun });
222
233
  const aggregateSubject = aggregate.subject;
223
- const capWarning = participantCapWarning(config, participantCount);
234
+ const capWarning = participantCapWarning(plan.caps, participantCount);
224
235
  const aggregateWarnings = [
225
236
  ...externalCommsWarnings,
226
237
  ...(capWarning === undefined ? [] : [capWarning]),
@@ -239,8 +250,8 @@ export async function finishCuaRun(setup, finish, ran) {
239
250
  ...(failFastReason === undefined ? {} : { failFastReason }),
240
251
  });
241
252
  const adapterWarnings = [];
242
- const scorerResult = await applyBrowserAdapterHooks({
243
- hooks,
253
+ const scorerResult = await applyBrowserScorer({
254
+ scorer: input.scorer,
244
255
  bundle,
245
256
  context: {
246
257
  bundle,
@@ -248,13 +259,12 @@ export async function finishCuaRun(setup, finish, ran) {
248
259
  labId: plan.labId,
249
260
  runId,
250
261
  actor: descriptor.id,
251
- backend: "cua",
262
+ route: "computer-use",
252
263
  dryRun,
253
- laneCount: participantCount,
264
+ participantCount,
254
265
  },
255
266
  sanitize: (text) => redactText(scrubKnownValues(text)),
256
267
  warnings: adapterWarnings,
257
- hookLabel: "cuaHooks",
258
268
  ...(input.scorerProvenance === undefined ? {} : { scorerProvenance: input.scorerProvenance }),
259
269
  });
260
270
  // The one final verdict fold: scoring can only make the judged verdict stricter.
@@ -264,7 +274,7 @@ export async function finishCuaRun(setup, finish, ran) {
264
274
  const finished = await run.finish(bundle);
265
275
  const observer = await finished.renderObserver();
266
276
  streams.attachFinal(observer);
267
- const execution = judgeExecution(computerUseExecutionFailures(outcomes, observer), OUTCOME_POLICIES["computer-use"]);
277
+ const execution = judgeExecution(computerUseExecutionFailures(outcomes, observer, runId), OUTCOME_POLICIES["computer-use"]);
268
278
  const result = cuaLabResult({
269
279
  labId: plan.labId,
270
280
  cwd,
@@ -4,14 +4,15 @@ import type { LabConfig } from "../../lab/types.js";
4
4
  import { type ComputerUseRefusal } from "./plan.js";
5
5
  import { type ComputerUseRunInput, type CuaActorLabResult, type RunCuaActorLabOptions } from "./types.js";
6
6
  /**
7
- * The library entry for a computer-use lab. It plans the config with planComputerUseLab and runs
7
+ * Plans and runs a computer-use lab in one call. It is not exported from src/index.ts; tests call
8
+ * it. It plans the config with planComputerUseLab and runs
8
9
  * the plan with runComputerUsePlan, whose run scope and withTransientCommsSecrets wrapper cover the
9
10
  * run and its analysis.
10
11
  */
11
12
  export declare function runCuaActorLab(options: RunCuaActorLabOptions): Promise<CuaActorLabResult>;
12
13
  /**
13
14
  * A refused computer-use lab's result, at the refusal's stage: a before-scope refusal has its own
14
- * envelope and no analysis record; the others come after the cwd checks, and the lane cap after
15
+ * envelope and no analysis record; the others come after the cwd checks, and the participant cap after
15
16
  * the personas are read.
16
17
  */
17
18
  export declare function computerUseLabRefusal(options: RunCuaActorLabOptions, refusal: ComputerUseRefusal): Promise<CuaActorLabResult>;
@@ -26,8 +27,7 @@ export declare function admitComputerUsePlan(plan: ComputerUsePlan, input: Compu
26
27
  * Run a computer-use plan: its local checks, then the run. The run scope in runAdmittedCuaRun
27
28
  * finalizes any status record the run opened, on every exit, so a test or library caller does not
28
29
  * leave the 5 s status cadence writing into a directory something else is deleting (an unrelated
29
- * ENOTEMPTY). Participants and the brain (model and local agent) come from the plan. `config` is
30
- * still read for values the plan does not carry yet (persona ids, comms settings, the
31
- * per-participant cap) and by the compatibility hooks, which take the whole config.
30
+ * ENOTEMPTY). Participants, the brain, the subject, the caps and the residual config come from the
31
+ * plan. `config` is what the caller's createProvider and inProcess executor receive.
32
32
  */
33
33
  export declare function runComputerUsePlan(plan: ComputerUsePlan, input: ComputerUseRunInput, config: LabConfig): Promise<CuaActorLabResult>;
@@ -1,6 +1,6 @@
1
1
  // The computer-use lab backend: a subject (an app-url the caller provisioned, or a repo the
2
- // lab clones AND serves in-sandbox) driven by a REGISTRY-RESOLVED computer-use actor inside a
3
- // hosted E2B desktop. This is the path that makes `actors[].type` load-bearing — the
2
+ // lab clones and serves in-sandbox) driven by a registry-resolved computer-use actor inside a
3
+ // hosted E2B desktop. On this path `actors[].type` selects the actor: the
4
4
  // descriptor returned by the registry runs the session; the lab provisions the desktop and
5
5
  // subject, composes the prompt from config, persists the evidence bundle, and tears down.
6
6
  //
@@ -8,42 +8,45 @@
8
8
  // - The desktop is created via the shared loader in src/substrates/e2b/sdk.ts with
9
9
  // kill-on-timeout lifecycle, so a dead host process can never orphan a sandbox past its
10
10
  // server-side deadline.
11
- // - Env placement follows the doctrine (docs/principles/invariants-and-defaults.md): the
12
- // ACTOR's key never enters the sandbox (the model drives from outside via the provider API);
13
- // the SUBJECT's declared env NAMES are provisioned in on the clone route — values come from
11
+ // - Env placement follows the placement rule (docs/principles/invariants-and-defaults.md): the
12
+ // actor's key never enters the sandbox (the model drives from outside via the provider API);
13
+ // the subject's declared env names are provisioned in on the clone route; values come from
14
14
  // the caller's environment and are never logged or persisted.
15
15
  // - The live stream URL is runtime-only (carries an auth key) and is never persisted into run
16
- // artifacts — only its presence is recorded.
16
+ // artifacts; only its presence is recorded.
17
17
  // - Evidence redaction is mode-aware (docs/principles/invariants-and-defaults.md, the
18
- // capture-vs-publish rule): screenshots persist RAW (full fidelity) by default into gitignored
18
+ // capture-vs-publish rule): screenshots persist raw (full fidelity) by default into gitignored
19
19
  // .humanish/; `policies.redactScreenshots: true` opts into blur-at-capture for a share-as-is
20
- // bundle. Length-only typed text and text redaction of reasoning/messages are UNCONDITIONAL;
21
- // harness errors are redacted at THIS boundary; the bundle's `stream.actor` carries the
20
+ // bundle. Length-only typed text and text redaction of reasoning/messages are unconditional;
21
+ // harness errors are redacted at this boundary; the bundle's `stream.actor` carries the
22
22
  // conformant humanish.actor-trace.v1 projection, whose `redaction.screenshots` records the
23
- // run's actual mode ("raw" | "blurred" | "n/a") — every label downstream derives from it.
23
+ // run's actual mode ("raw" | "blurred" | "n/a"), and every label downstream derives from it.
24
24
  import { withTransientCommsSecrets } from "../../run/transient-comms-secrets.js";
25
25
  import path from "node:path";
26
26
  import { completeAutomaticAnalysis } from "../../analysis/automatic-completion.js";
27
27
  import { runScope } from "../../run/run.js";
28
28
  import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
29
- import { computerUseInputWithScorer } from "../../lab/route-inputs.js";
30
- import { planComputerUseLab } from "./plan.js";
29
+ import { browserRouteScorer } from "../../lab/adapter-scorer-loader.js";
30
+ import { withLateScorer } from "../../lab/route-inputs.js";
31
+ import { callerDrivingOf, planComputerUseLab } from "./plan.js";
31
32
  import { finishCuaRun } from "./result.js";
32
- import { runLabParticipants } from "./run-lanes.js";
33
+ import { runLabParticipants } from "./live-phase.js";
33
34
  import { admitCuaRun, refuseCuaLab, startCuaRun } from "./setup.js";
34
- import { CUA_ACTOR_LAB_SCHEMA, } from "./types.js";
35
+ import {} from "./types.js";
36
+ import { studyResultIdentity } from "../../run/study-result.js";
35
37
  /**
36
- * The library entry for a computer-use lab. It plans the config with planComputerUseLab and runs
38
+ * Plans and runs a computer-use lab in one call. It is not exported from src/index.ts; tests call
39
+ * it. It plans the config with planComputerUseLab and runs
37
40
  * the plan with runComputerUsePlan, whose run scope and withTransientCommsSecrets wrapper cover the
38
41
  * run and its analysis.
39
42
  */
40
43
  export async function runCuaActorLab(options) {
41
- const { config, dryRun, lab, ...input } = options;
44
+ const { config, dryRun, ...input } = options;
42
45
  // planComputerUseLab makes every configuration refusal, in the order this route always has.
43
46
  const planned = planComputerUseLab(config, {
44
47
  dryRun,
45
- ...(lab === undefined ? {} : { lab }),
46
- ...(input.hooks === undefined ? {} : { hooks: input.hooks }),
48
+ hasRunSession: input.deps?.runSession !== undefined,
49
+ driving: callerDrivingOf(input),
47
50
  ...(input.countOverride === undefined ? {} : { countOverride: input.countOverride }),
48
51
  ...(input.rerun === undefined ? {} : { rerun: input.rerun }),
49
52
  });
@@ -53,17 +56,16 @@ export async function runCuaActorLab(options) {
53
56
  }
54
57
  /**
55
58
  * A refused computer-use lab's result, at the refusal's stage: a before-scope refusal has its own
56
- * envelope and no analysis record; the others come after the cwd checks, and the lane cap after
59
+ * envelope and no analysis record; the others come after the cwd checks, and the participant cap after
57
60
  * the personas are read.
58
61
  */
59
62
  export async function computerUseLabRefusal(options, refusal) {
60
63
  const { config, dryRun } = options;
61
64
  if (refusal.stage === "before-scope")
62
65
  return {
63
- schema: CUA_ACTOR_LAB_SCHEMA,
66
+ ...studyResultIdentity("computer-use", config.id),
64
67
  ok: false,
65
68
  cwd: path.resolve(options.cwd),
66
- labId: config.id,
67
69
  actor: config.actors[0]?.type ?? "",
68
70
  dryRun,
69
71
  runId: options.runId ?? "not-created",
@@ -72,9 +74,9 @@ export async function computerUseLabRefusal(options, refusal) {
72
74
  warnings: [],
73
75
  error: { code: refusal.code, message: refusal.message },
74
76
  };
75
- // The other refusals come after the cwd checks, and the lane cap after the personas are read.
77
+ // The other refusals come after the cwd checks, and the participant cap after the personas are read.
76
78
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
77
- return completeAutomaticAnalysis(await refuseCuaLab(options, refusal), undefined, analysis.ok ? analysis.config : undefined, options.automaticAnalysis, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
79
+ return completeAutomaticAnalysis(await refuseCuaLab(options, refusal), undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
78
80
  }
79
81
  /**
80
82
  * runLab's step for a computer-use plan. It runs the plan's local checks (admitCuaRun: the
@@ -92,24 +94,22 @@ export async function admitComputerUsePlan(plan, input, config) {
92
94
  return {
93
95
  ok: true,
94
96
  run: async (scorer) => {
95
- const running = computerUseInputWithScorer(input, scorer);
96
- // The scorer's hooks wrap the admitted bag, so the runSession, provider and desktop the
97
- // checks admitted stay the ones the run uses.
98
- const admitted = { ...admission.admitted, hooks: running.hooks ?? admission.admitted.hooks };
99
- return cuaOutcome(await runAdmittedCuaRun(plan, running, admitted));
97
+ // The scorer joins the input only; the runSession, provider and desktop the checks admitted
98
+ // stay the ones the run uses.
99
+ const running = withLateScorer(input, scorer, browserRouteScorer);
100
+ return cuaOutcome(await runAdmittedCuaRun(plan, running, admission.admitted));
100
101
  },
101
102
  };
102
103
  }
103
104
  function cuaOutcome(result) {
104
- return { route: "computer-use", backend: "cua", result };
105
+ return { route: "computer-use", result };
105
106
  }
106
107
  /**
107
108
  * Run a computer-use plan: its local checks, then the run. The run scope in runAdmittedCuaRun
108
109
  * finalizes any status record the run opened, on every exit, so a test or library caller does not
109
110
  * leave the 5 s status cadence writing into a directory something else is deleting (an unrelated
110
- * ENOTEMPTY). Participants and the brain (model and local agent) come from the plan. `config` is
111
- * still read for values the plan does not carry yet (persona ids, comms settings, the
112
- * per-participant cap) and by the compatibility hooks, which take the whole config.
111
+ * ENOTEMPTY). Participants, the brain, the subject, the caps and the residual config come from the
112
+ * plan. `config` is what the caller's createProvider and inProcess executor receive.
113
113
  */
114
114
  export async function runComputerUsePlan(plan, input, config) {
115
115
  const admission = await admitCuaRun(plan, input, config);
@@ -129,9 +129,12 @@ function runAdmittedCuaRun(plan, input, admitted) {
129
129
  });
130
130
  }
131
131
  function completeCuaAnalysis(plan, input, result, finished) {
132
- return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input.automaticAnalysis, {
132
+ // A local VM study whose cleanup is unconfirmed records a skip instead of analyzing.
133
+ const refusal = input.localVm?.analysisRefusal;
134
+ return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
133
135
  ...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
134
136
  preferLargerOutput: plan.analysis?.preferLargerOutput === true,
137
+ ...(refusal === undefined ? {} : { refusal }),
135
138
  });
136
139
  }
137
140
  async function runPlanInScope(plan, input, admitted, scope) {
@@ -1,21 +1,21 @@
1
1
  import type { CuaLoopResult } from "../../actors/computer-use/loop.js";
2
2
  import { type SessionEnding } from "../../run/judge.js";
3
3
  /**
4
- * A goal_satisfied lane counts as a self-reported blocker ONLY when its final narrative contradicts
5
- * the goal AND the run's own stop predicate did NOT fire. A matched stopWhen is independent,
6
- * structured completion evidence, so it overrides a text scan of the free-form narrative — which can
7
- * otherwise trip on the subject app's OWN quoted copy (e.g. a relayed "cannot be undone" banner).
8
- * Resolved-arc segments never block the verdict (#453). Returns the offending reason, or undefined
9
- * when the lane is a clean pass. Exported for testing.
4
+ * A goal_satisfied participant counts as a self-reported blocker only when its final narrative contradicts
5
+ * the goal and the run's own stop predicate did not fire. A matched stopWhen is independent,
6
+ * structured completion evidence, so it overrides a text scan of the free-form narrative, which can
7
+ * otherwise trip on the subject app's own quoted copy (e.g. a relayed "cannot be undone" banner).
8
+ * Resolved-arc segments never block the verdict. Returns the offending reason, or undefined
9
+ * when the participant is a clean pass. Exported for testing.
10
10
  */
11
11
  export declare function resolveSelfReportedBlocker(session: CuaLoopResult | undefined): string | undefined;
12
12
  /** A session's ending, reduced to what the judge's engagement and blocker rules read. */
13
13
  export declare function sessionEnding(session: CuaLoopResult): SessionEnding;
14
14
  /**
15
- * Friction is independent of how a completed session ended (#657). Read the participant's
15
+ * Friction is independent of how a completed session ended. Read the participant's
16
16
  * redacted messages, including earlier reports, rather than the harness-owned reason that
17
17
  * stopWhen/dwell writes. Reasoning, observations, and notices are not participant reports.
18
- * Resolved arcs still count (#453); quoted copy and negated reports still do not. This read
18
+ * Resolved arcs still count; quoted copy and negated reports still do not. This read
19
19
  * never changes the verdict. Exported for testing.
20
20
  */
21
21
  export declare function resolveSelfReportedFriction(session: CuaLoopResult | undefined): string | undefined;