humanish 0.106.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/AGENTS.md +4 -2
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +24 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -6
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +31 -4
  16. package/dist/actors/codex/qualified-versions.js +51 -6
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +10 -8
  45. package/dist/actors/contract.js +7 -1
  46. package/dist/actors/local-agent/cli.js +1 -1
  47. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  48. package/dist/actors/scripted-browser/journey.js +15 -4
  49. package/dist/actors/scripted-browser/steps.js +18 -0
  50. package/dist/actors/scripted-browser/types.d.ts +11 -1
  51. package/dist/actors/stop-conditions.js +1 -3
  52. package/dist/analysis/automatic-completion.d.ts +13 -8
  53. package/dist/analysis/automatic-completion.js +14 -8
  54. package/dist/analysis/automatic-config.d.ts +1 -1
  55. package/dist/analysis/automatic-config.js +2 -2
  56. package/dist/analysis/automatic.d.ts +10 -4
  57. package/dist/analysis/automatic.js +17 -13
  58. package/dist/analysis/diagnostics.d.ts +23 -0
  59. package/dist/analysis/diagnostics.js +112 -0
  60. package/dist/analysis/evidence-sources.js +2 -2
  61. package/dist/analysis/evidence.js +6 -6
  62. package/dist/analysis/execute.d.ts +7 -1
  63. package/dist/analysis/execute.js +39 -12
  64. package/dist/analysis/job.d.ts +8 -5
  65. package/dist/analysis/job.js +15 -14
  66. package/dist/analysis/load.d.ts +1 -1
  67. package/dist/analysis/load.js +5 -5
  68. package/dist/analysis/provider.d.ts +9 -1
  69. package/dist/analysis/restricted-codex.d.ts +2 -0
  70. package/dist/analysis/restricted-codex.js +10 -1
  71. package/dist/analysis/service.d.ts +2 -0
  72. package/dist/analysis/service.js +31 -12
  73. package/dist/analysis/sharing.d.ts +2 -2
  74. package/dist/analysis/sharing.js +5 -5
  75. package/dist/analysis/store-executions.d.ts +5 -5
  76. package/dist/analysis/store-executions.js +12 -12
  77. package/dist/analysis/store.d.ts +4 -4
  78. package/dist/analysis/store.js +13 -13
  79. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  80. package/dist/cli/commands/analysis-signals.js +4 -1
  81. package/dist/cli/commands/analyze.js +4 -2
  82. package/dist/cli/commands/comms.js +8 -1
  83. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  84. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  85. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  86. package/dist/cli/commands/lab-route-preview.js +3 -4
  87. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  88. package/dist/cli/commands/lab-route-run.js +6 -2
  89. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  90. package/dist/cli/commands/lab-route-scripted.js +0 -1
  91. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  92. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  93. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  94. package/dist/cli/commands/lab-route-terminal.js +0 -1
  95. package/dist/cli/commands/lab-run.js +76 -45
  96. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  97. package/dist/cli/commands/lab.js +12 -6
  98. package/dist/cli/commands/observe.js +22 -0
  99. package/dist/cli/commands/run-signals.d.ts +30 -0
  100. package/dist/cli/commands/run-signals.js +146 -0
  101. package/dist/cli/commands/runs.js +10 -8
  102. package/dist/cli/commands/watch.js +12 -10
  103. package/dist/cli/doctor.d.ts +3 -0
  104. package/dist/cli/doctor.js +10 -2
  105. package/dist/cli/io.d.ts +5 -4
  106. package/dist/cli/io.js +12 -8
  107. package/dist/cli/program.js +3 -3
  108. package/dist/cli/renamed-options.d.ts +11 -0
  109. package/dist/cli/renamed-options.js +18 -0
  110. package/dist/cli/telemetry.d.ts +2 -2
  111. package/dist/cli/telemetry.js +1 -1
  112. package/dist/comms/capture-surface.d.ts +1 -1
  113. package/dist/comms/catch-host.d.ts +1 -1
  114. package/dist/comms/connections.js +4 -4
  115. package/dist/comms/external-evidence.d.ts +27 -0
  116. package/dist/comms/external-evidence.js +93 -0
  117. package/dist/comms/lease-store.js +7 -7
  118. package/dist/comms/types.js +1 -1
  119. package/dist/evidence/browser-hygiene.d.ts +1 -1
  120. package/dist/evidence/browser-hygiene.js +1 -1
  121. package/dist/evidence/redaction.js +1 -1
  122. package/dist/evidence/secret-scrub.d.ts +9 -0
  123. package/dist/evidence/secret-scrub.js +96 -0
  124. package/dist/feedback/draft.js +7 -9
  125. package/dist/feedback/export-bundle.js +4 -4
  126. package/dist/feedback/export.js +9 -9
  127. package/dist/feedback/feedback.d.ts +1 -1
  128. package/dist/index.d.ts +3 -6
  129. package/dist/index.js +3 -6
  130. package/dist/keys/key-resolution.d.ts +3 -1
  131. package/dist/keys/key-resolution.js +18 -16
  132. package/dist/lab/adapter-extension.d.ts +28 -6
  133. package/dist/lab/adapter-extension.js +65 -126
  134. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  135. package/dist/lab/adapter-scorer-loader.js +24 -0
  136. package/dist/lab/composition-rules.d.ts +2 -0
  137. package/dist/lab/composition-rules.js +35 -26
  138. package/dist/lab/config.js +28 -26
  139. package/dist/lab/device-presets.d.ts +2 -2
  140. package/dist/lab/discover.js +1 -3
  141. package/dist/lab/doctor.d.ts +44 -9
  142. package/dist/lab/doctor.js +149 -41
  143. package/dist/lab/init-plan.js +1 -3
  144. package/dist/lab/keys.js +1 -1
  145. package/dist/lab/lab-deps.d.ts +85 -0
  146. package/dist/lab/lab-deps.js +4 -0
  147. package/dist/lab/parse/actors.js +8 -7
  148. package/dist/lab/parse/comms.js +3 -2
  149. package/dist/lab/parse/execution.js +3 -2
  150. package/dist/lab/parse/subject-state.js +2 -1
  151. package/dist/lab/parse/subject.js +2 -1
  152. package/dist/lab/parse/values.d.ts +0 -1
  153. package/dist/lab/parse/values.js +0 -3
  154. package/dist/lab/persona-resolve.d.ts +3 -3
  155. package/dist/lab/persona-resolve.js +4 -4
  156. package/dist/lab/persona.js +1 -3
  157. package/dist/lab/plan-base.d.ts +6 -2
  158. package/dist/lab/plan-base.js +22 -7
  159. package/dist/lab/plan-participants.d.ts +5 -5
  160. package/dist/lab/plan-participants.js +2 -2
  161. package/dist/lab/plan-types.d.ts +33 -7
  162. package/dist/lab/plan.d.ts +3 -11
  163. package/dist/lab/plan.js +18 -42
  164. package/dist/lab/preflight-result.js +0 -2
  165. package/dist/lab/preflight.d.ts +0 -3
  166. package/dist/lab/preflight.js +1 -1
  167. package/dist/lab/requirements.d.ts +20 -0
  168. package/dist/lab/requirements.js +54 -0
  169. package/dist/lab/route-inputs.d.ts +23 -12
  170. package/dist/lab/route-inputs.js +48 -51
  171. package/dist/lab/routing.d.ts +19 -24
  172. package/dist/lab/routing.js +14 -47
  173. package/dist/lab/run-lab-events.d.ts +6 -11
  174. package/dist/lab/run-lab-events.js +3 -11
  175. package/dist/lab/run-lab-homes.d.ts +64 -0
  176. package/dist/lab/run-lab-homes.js +3 -0
  177. package/dist/lab/run-lab-options.d.ts +12 -66
  178. package/dist/lab/run-lab-options.js +45 -275
  179. package/dist/lab/summary.d.ts +9 -4
  180. package/dist/lab/summary.js +15 -8
  181. package/dist/lab/types.d.ts +132 -132
  182. package/dist/lab/validation.d.ts +15 -15
  183. package/dist/lab/validation.js +28 -28
  184. package/dist/lab/warnings.js +20 -19
  185. package/dist/observer/artifact.d.ts +1 -1
  186. package/dist/observer/artifact.js +3 -3
  187. package/dist/observer/data.js +2 -2
  188. package/dist/observer/render.js +2 -2
  189. package/dist/observer/run-routes.d.ts +1 -1
  190. package/dist/observer/run-routes.js +5 -5
  191. package/dist/observer/serve.d.ts +17 -0
  192. package/dist/observer/serve.js +34 -3
  193. package/dist/observer-app.html +1 -1
  194. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  195. package/dist/routes/computer-use/bundle-parts.js +10 -3
  196. package/dist/routes/computer-use/bundle.d.ts +4 -11
  197. package/dist/routes/computer-use/bundle.js +9 -15
  198. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  199. package/dist/routes/computer-use/diagnostics.js +1 -1
  200. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  201. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  202. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  203. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  204. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  205. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  206. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  207. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  208. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  209. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  210. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  211. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  212. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  213. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  214. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  215. package/dist/routes/computer-use/external-comms.js +19 -43
  216. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  217. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  218. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  219. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  220. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  221. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  222. package/dist/routes/computer-use/live-flush.js +19 -27
  223. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
  224. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  225. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  226. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  227. package/dist/routes/computer-use/local-vm.js +39 -66
  228. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  229. package/dist/routes/computer-use/participant-desktop.js +5 -25
  230. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  231. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  232. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  233. package/dist/routes/computer-use/participant-facts.js +12 -1
  234. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  235. package/dist/routes/computer-use/participant-model.js +58 -33
  236. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  237. package/dist/routes/computer-use/participant-prompt.js +4 -4
  238. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  239. package/dist/routes/computer-use/participant-runs.js +8 -8
  240. package/dist/routes/computer-use/plan.d.ts +21 -29
  241. package/dist/routes/computer-use/plan.js +59 -65
  242. package/dist/routes/computer-use/preflight.d.ts +6 -11
  243. package/dist/routes/computer-use/preflight.js +26 -18
  244. package/dist/routes/computer-use/rerun-selection.js +10 -6
  245. package/dist/routes/computer-use/result.d.ts +1 -1
  246. package/dist/routes/computer-use/result.js +40 -30
  247. package/dist/routes/computer-use/route.d.ts +3 -4
  248. package/dist/routes/computer-use/route.js +21 -19
  249. package/dist/routes/computer-use/self-report.d.ts +2 -2
  250. package/dist/routes/computer-use/self-report.js +4 -4
  251. package/dist/routes/computer-use/setup.d.ts +8 -17
  252. package/dist/routes/computer-use/setup.js +98 -86
  253. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  254. package/dist/routes/computer-use/single-bundle.js +20 -25
  255. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  256. package/dist/routes/computer-use/subject-projection.js +20 -19
  257. package/dist/routes/computer-use/types.d.ts +169 -211
  258. package/dist/routes/computer-use/types.js +13 -6
  259. package/dist/routes/preview.js +0 -1
  260. package/dist/routes/scripted/bundle.d.ts +3 -6
  261. package/dist/routes/scripted/bundle.js +11 -16
  262. package/dist/routes/scripted/plan.d.ts +5 -7
  263. package/dist/routes/scripted/plan.js +6 -4
  264. package/dist/routes/scripted/result.d.ts +4 -1
  265. package/dist/routes/scripted/result.js +10 -6
  266. package/dist/routes/scripted/route.js +10 -11
  267. package/dist/routes/scripted/scenario.d.ts +1 -1
  268. package/dist/routes/scripted/scenario.js +1 -1
  269. package/dist/routes/scripted/setup.d.ts +3 -2
  270. package/dist/routes/scripted/setup.js +22 -21
  271. package/dist/routes/scripted/subject.d.ts +8 -3
  272. package/dist/routes/scripted/subject.js +11 -6
  273. package/dist/routes/scripted/surface-records.js +1 -1
  274. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  275. package/dist/routes/scripted/surface-sessions.js +4 -4
  276. package/dist/routes/scripted/types.d.ts +19 -36
  277. package/dist/routes/scripted/types.js +1 -2
  278. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  279. package/dist/routes/shared-world/bundle.d.ts +2 -2
  280. package/dist/routes/shared-world/bundle.js +22 -26
  281. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  282. package/dist/routes/shared-world/checkpoints.js +4 -4
  283. package/dist/routes/shared-world/comms.d.ts +5 -4
  284. package/dist/routes/shared-world/comms.js +28 -41
  285. package/dist/routes/shared-world/external-public.d.ts +5 -5
  286. package/dist/routes/shared-world/external-public.js +19 -20
  287. package/dist/routes/shared-world/handoff.d.ts +4 -4
  288. package/dist/routes/shared-world/handoff.js +50 -50
  289. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  290. package/dist/routes/shared-world/lobby-code.js +13 -13
  291. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  292. package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
  293. package/dist/routes/shared-world/plan.d.ts +2 -6
  294. package/dist/routes/shared-world/plan.js +1 -2
  295. package/dist/routes/shared-world/provenance.d.ts +4 -4
  296. package/dist/routes/shared-world/provenance.js +4 -4
  297. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  298. package/dist/routes/shared-world/provisioned.js +48 -41
  299. package/dist/routes/shared-world/result.js +31 -19
  300. package/dist/routes/shared-world/route.js +37 -41
  301. package/dist/routes/shared-world/setup.d.ts +5 -4
  302. package/dist/routes/shared-world/setup.js +12 -14
  303. package/dist/routes/shared-world/types.d.ts +53 -126
  304. package/dist/routes/shared-world/types.js +2 -2
  305. package/dist/routes/terminal/adapter.d.ts +8 -8
  306. package/dist/routes/terminal/adapter.js +28 -125
  307. package/dist/routes/terminal/bundle.d.ts +7 -12
  308. package/dist/routes/terminal/bundle.js +24 -34
  309. package/dist/routes/terminal/credentials.d.ts +2 -2
  310. package/dist/routes/terminal/credentials.js +16 -16
  311. package/dist/routes/terminal/dry-run.d.ts +1 -1
  312. package/dist/routes/terminal/dry-run.js +9 -11
  313. package/dist/routes/terminal/encoding.d.ts +1 -1
  314. package/dist/routes/terminal/encoding.js +2 -2
  315. package/dist/routes/terminal/ledger.d.ts +6 -6
  316. package/dist/routes/terminal/ledger.js +9 -9
  317. package/dist/routes/terminal/live-finish.d.ts +1 -2
  318. package/dist/routes/terminal/live-finish.js +21 -20
  319. package/dist/routes/terminal/live-sandbox.d.ts +4 -2
  320. package/dist/routes/terminal/live-sandbox.js +25 -21
  321. package/dist/routes/terminal/participant-text.d.ts +23 -0
  322. package/dist/routes/terminal/participant-text.js +165 -0
  323. package/dist/routes/terminal/plan.d.ts +2 -6
  324. package/dist/routes/terminal/plan.js +13 -9
  325. package/dist/routes/terminal/recorder.d.ts +6 -1
  326. package/dist/routes/terminal/recorder.js +12 -4
  327. package/dist/routes/terminal/result.js +4 -4
  328. package/dist/routes/terminal/route.js +26 -26
  329. package/dist/routes/terminal/runtime.d.ts +3 -2
  330. package/dist/routes/terminal/runtime.js +3 -3
  331. package/dist/routes/terminal/sandbox.d.ts +5 -3
  332. package/dist/routes/terminal/sandbox.js +13 -16
  333. package/dist/routes/terminal/session.js +16 -14
  334. package/dist/routes/terminal/token-usage.js +5 -5
  335. package/dist/routes/terminal/trace.d.ts +5 -8
  336. package/dist/routes/terminal/trace.js +9 -64
  337. package/dist/routes/terminal/types.d.ts +85 -93
  338. package/dist/routes/terminal/types.js +9 -4
  339. package/dist/run/active-runs.d.ts +13 -0
  340. package/dist/run/active-runs.js +12 -0
  341. package/dist/run/bundle-shape.d.ts +2 -1
  342. package/dist/run/bundle-shape.js +4 -4
  343. package/dist/run/bundle.d.ts +63 -56
  344. package/dist/run/bundle.js +9 -8
  345. package/dist/run/cost-summary.js +3 -2
  346. package/dist/run/costs.d.ts +6 -6
  347. package/dist/run/costs.js +10 -10
  348. package/dist/run/detail.d.ts +5 -5
  349. package/dist/run/detail.js +6 -6
  350. package/dist/run/dry-run.js +5 -12
  351. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  352. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  353. package/dist/run/feedback-shape.js +1 -1
  354. package/dist/run/judge.d.ts +16 -4
  355. package/dist/run/judge.js +24 -7
  356. package/dist/run/locate.d.ts +2 -0
  357. package/dist/run/locate.js +3 -1
  358. package/dist/run/outcomes.d.ts +3 -3
  359. package/dist/run/outcomes.js +3 -3
  360. package/dist/run/participant-records.d.ts +2 -2
  361. package/dist/run/participant-records.js +2 -2
  362. package/dist/run/paths.js +1 -1
  363. package/dist/run/pricing.d.ts +19 -9
  364. package/dist/run/pricing.js +30 -18
  365. package/dist/run/projection.d.ts +13 -13
  366. package/dist/run/projection.js +8 -8
  367. package/dist/run/reclaim.d.ts +7 -1
  368. package/dist/run/reclaim.js +24 -4
  369. package/dist/run/results.d.ts +1 -1
  370. package/dist/run/run-index.d.ts +1 -1
  371. package/dist/run/run-index.js +11 -11
  372. package/dist/run/run.d.ts +4 -2
  373. package/dist/run/run.js +9 -5
  374. package/dist/run/sandbox-receipts.d.ts +4 -4
  375. package/dist/run/sandbox-receipts.js +4 -4
  376. package/dist/run/shared-world-evidence.d.ts +47 -47
  377. package/dist/run/shared-world-shape.d.ts +3 -3
  378. package/dist/run/shared-world-shape.js +11 -11
  379. package/dist/run/stats.d.ts +5 -5
  380. package/dist/run/stats.js +8 -8
  381. package/dist/run/status.d.ts +16 -6
  382. package/dist/run/status.js +31 -8
  383. package/dist/run/streams.d.ts +26 -19
  384. package/dist/run/terminal-contract.d.ts +5 -5
  385. package/dist/run/terminal-contract.js +4 -4
  386. package/dist/run/transient-comms-secrets.d.ts +5 -0
  387. package/dist/run/transient-comms-secrets.js +12 -0
  388. package/dist/run-lab.d.ts +36 -34
  389. package/dist/run-lab.js +41 -37
  390. package/dist/subject/desktop-cli.d.ts +1 -1
  391. package/dist/subject/desktop-cli.js +1 -1
  392. package/dist/subject/local-tree-archive.d.ts +1 -1
  393. package/dist/subject/local-tree-archive.js +4 -4
  394. package/dist/subject/local-tree.d.ts +2 -2
  395. package/dist/subject/local-tree.js +1 -1
  396. package/dist/subject/node-bootstrap.d.ts +1 -1
  397. package/dist/subject/node-bootstrap.js +4 -4
  398. package/dist/subject/runtime.js +5 -5
  399. package/dist/subject/serve.js +1 -1
  400. package/dist/subject/steps.d.ts +4 -4
  401. package/dist/subject/steps.js +5 -5
  402. package/dist/substrates/desktop-session.d.ts +2 -0
  403. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  404. package/dist/substrates/e2b/cdp-probe.js +1 -1
  405. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  406. package/dist/substrates/e2b/desktop-browser.js +4 -4
  407. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  408. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  409. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  410. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  411. package/dist/substrates/e2b/desktop-media.js +2 -2
  412. package/dist/substrates/e2b/sandbox.d.ts +2 -0
  413. package/dist/substrates/e2b/sandbox.js +22 -8
  414. package/dist/substrates/e2b/sdk.d.ts +12 -1
  415. package/dist/substrates/e2b/sdk.js +30 -9
  416. package/dist/substrates/local/runtime-host.d.ts +2 -0
  417. package/dist/substrates/local/runtime-host.js +6 -0
  418. package/dist/tui/actions.d.ts +7 -5
  419. package/dist/tui/actions.js +18 -9
  420. package/dist/tui-app.js +42 -42
  421. package/dist/verify/actor.d.ts +10 -10
  422. package/dist/verify/actor.js +15 -15
  423. package/dist/verify/artifacts.d.ts +1 -1
  424. package/dist/verify/artifacts.js +3 -3
  425. package/dist/verify/costs.d.ts +2 -2
  426. package/dist/verify/costs.js +2 -2
  427. package/dist/verify/liveness.d.ts +1 -1
  428. package/dist/verify/liveness.js +4 -1
  429. package/dist/verify/rerun.d.ts +1 -1
  430. package/dist/verify/rerun.js +1 -1
  431. package/dist/verify/shared-world.js +2 -2
  432. package/dist/verify/verify.js +6 -6
  433. package/docs/README.md +1 -1
  434. package/docs/architecture/actor-contract.md +60 -22
  435. package/docs/architecture/desktop-sessions.md +9 -9
  436. package/docs/architecture/external-public-shared-world.md +5 -0
  437. package/docs/architecture/observer.md +4 -4
  438. package/docs/architecture/restricted-codex-analysis.md +40 -4
  439. package/docs/architecture/state-driven-executor.md +4 -5
  440. package/docs/architecture/task-protocol-support.md +3 -5
  441. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  442. package/docs/contracts/run-bundle.md +10 -8
  443. package/docs/contracts/schemas.md +109 -53
  444. package/docs/contracts/study-analysis.md +24 -0
  445. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  446. package/docs/product/automatic-analysis.md +1 -0
  447. package/docs/ramp/README.md +2 -1
  448. package/package.json +4 -4
  449. package/skills/humanish/SKILL.md +3 -2
  450. package/skills/humanish/agents/openai.yaml +1 -1
  451. package/dist/deprecated.d.ts +0 -90
  452. package/dist/deprecated.js +0 -106
  453. package/dist/lab/bag-overrides.d.ts +0 -18
  454. package/dist/lab/bag-overrides.js +0 -121
  455. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  456. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  457. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  458. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  459. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -1,96 +1,49 @@
1
- // The typed homes on RunLabOptions and the one place they meet the route hook bags. runLab calls
2
- // normalizeRunLabOptions first: it refuses an option the route cannot honor, or a new option set
3
- // together with the old field it replaces, and otherwise maps each new option into the bag the
4
- // route reads today. Old fields pass through untouched, so they keep their exact behavior.
1
+ // The typed homes on RunLabOptions. runLab calls normalizeRunLabOptions first: it refuses an option
2
+ // the route cannot honor and otherwise passes the typed options to the route, with env copied and
3
+ // onEvent turned into the emitter. The package's runLab refuses the removed bags
4
+ // (removedOptionRefusal).
5
5
  import path from "node:path";
6
6
  import { CUA_ACTOR_LAB_SCHEMA } from "../routes/computer-use/types.js";
7
7
  import { SCRIPTED_BROWSER_LAB_SCHEMA } from "../routes/scripted/types.js";
8
8
  import { CONCURRENT_SHARED_WORLD_LAB_SCHEMA } from "../routes/shared-world/types.js";
9
- import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "../routes/terminal/types.js";
9
+ import { TERMINAL_PRODUCT_LAB_SCHEMA } from "../routes/terminal/types.js";
10
10
  import { isLocalBrowserLab } from "../substrates/local/runtime-config.js";
11
- import { defaultSharedWorldPhaseSink, defaultSubjectPhaseSink } from "../subject/steps.js";
12
- import { HOOK_MEMBERS, withHookOverrides } from "./bag-overrides.js";
13
11
  import { resolveLabDryRun } from "./plan.js";
14
- import { knownSecretValues, labEventEmitter, participantOf, phaseEvent, planEvent, } from "./run-lab-events.js";
12
+ import { knownSecretValues, labEventEmitter } from "./run-lab-events.js";
15
13
  import { rosterOf } from "./parse/actors.js";
16
- const conflict = (home, old) => ({
17
- ok: false,
18
- code: "HUMANISH_LAB_OPTION_CONFLICT",
19
- message: `RunLabOptions.${home} and ${old} are both set. ${old} is the older form of ${home}; set only ${home}.`,
20
- });
21
14
  const unsupported = (option, route, reason) => ({
22
15
  ok: false,
23
16
  code: "HUMANISH_LAB_OPTION_UNSUPPORTED",
24
17
  message: `RunLabOptions.${option} is not supported on the ${route} route: ${reason}`,
25
18
  });
26
- /**
27
- * Whether a caller's bag sets `key`, from its property descriptors: a data property counts when its
28
- * value is defined, an accessor counts without being called. Nothing the caller defined runs.
29
- */
30
- function hasMember(bag, key) {
31
- for (let source = bag ?? null; source !== null && source !== Object.prototype; source = Object.getPrototypeOf(source)) {
32
- const descriptor = Object.getOwnPropertyDescriptor(source, key);
33
- if (descriptor !== undefined)
34
- return "value" in descriptor ? descriptor.value !== undefined : true;
35
- }
36
- return false;
37
- }
38
- /**
39
- * Every old field the options set that has a new home, and whether its home is set too. Presence
40
- * comes from property descriptors (hasMember), so no getter of the caller's runs.
41
- */
42
- function oldFieldsInUse(options) {
43
- const pairs = [
44
- ["env", "cuaHooks", "env"],
45
- ["env", "scriptedHooks", "env"],
46
- ["env", "terminalHooks", "env"],
47
- ["env", "sharedWorldHooks", "env"],
48
- ["scorer", "cuaHooks", "score"],
49
- ["scorer", "cuaHooks", "deriveFeedback"],
50
- ["scorer", "cuaHooks", "deriveArtifacts"],
51
- ["scorer", "sharedWorldHooks", "score"],
52
- ["scorer", "sharedWorldHooks", "deriveFeedback"],
53
- ["scorer", "sharedWorldHooks", "deriveArtifacts"],
54
- ["scorer", "terminalHooks", "score"],
55
- ["scorer", "terminalHooks", "deriveFeedback"],
56
- ["prepareDesktop", "cuaHooks", "prepareDesktop"],
57
- ["prepareDesktop", "scriptedHooks", "prepareDesktop"],
58
- ["prepareDesktop", "sharedWorldHooks", "prepareDesktop"],
59
- ["onEvent", "cuaHooks", "onPreflight"],
60
- ["onEvent", "cuaHooks", "onPhase"],
61
- ["onEvent", "sharedWorldHooks", "onPhase"],
62
- ["onEvent", "automaticAnalysis", "onStart"],
63
- ["onStream", "cuaHooks", "onRuntimeStreamReady"],
64
- ["onStream", "cuaHooks", "onRuntimeStreamEnded"],
65
- ["onStream", "sharedWorldHooks", "onRuntimeStreamReady"],
66
- ["onStream", "sharedWorldHooks", "onRuntimeStreamEnded"],
67
- ["analysisSignal", "automaticAnalysis.deps", "signal"],
68
- ["createProvider", "cuaHooks", "buildProvider"],
69
- ["inProcess", "cuaHooks", "buildExecutor"],
70
- ["rerun.participantIds", "rerun", "laneIds"],
71
- ];
72
- const home = (name) => name === "rerun.participantIds"
73
- ? options.rerun?.participantIds !== undefined
74
- : options[name] !== undefined;
75
- const bagOf = (name) => name === "automaticAnalysis.deps"
76
- ? options.automaticAnalysis?.deps
77
- : options[name];
78
- return pairs
79
- .filter(([, bag, member]) => hasMember(bagOf(bag), member))
80
- .map(([name, bag, member]) => ({ home: name, old: `${bag}.${member}`, clash: home(name) }));
81
- }
82
- /** Old fields removed in the next minor with no replacement. They warn, and they never clash. */
83
- function retiredFieldsInUse(options) {
84
- return hasMember(options.cuaHooks, "createDesktopLane") ? ["cuaHooks.createDesktopLane"] : [];
85
- }
86
- const warned = new Set();
87
- /** One DeprecationWarning per old field per process. The bags' other test seams never warn. */
88
- function warnDeprecated(home, old) {
89
- if (warned.has(old))
90
- return;
91
- warned.add(old);
92
- const replacement = home === undefined ? "It has no replacement." : `Use RunLabOptions.${home}.`;
93
- process.emitWarning(`RunLabOptions.${old} is deprecated and is removed in the next minor. ${replacement}`, { type: "DeprecationWarning", code: "HUMANISH_RUN_LAB_OPTION_DEPRECATED" });
19
+ // Fields RunLabOptions no longer has, and where each one's job went.
20
+ const REMOVED_OPTIONS = {
21
+ cuaHooks: "Use scorer, createProvider, inProcess, prepareDesktop, env, onEvent and onStream.",
22
+ scriptedHooks: "Use prepareDesktop and env.",
23
+ terminalHooks: "Use scorer and env.",
24
+ sharedWorldHooks: "Use scorer, prepareDesktop, env, onEvent and onStream.",
25
+ automaticAnalysis: "Use onEvent (analysis-started, analysis-finished) and analysisSignal.",
26
+ lab: "The humanish CLI sets it.",
27
+ scorerProvenance: "The humanish CLI sets it.",
28
+ };
29
+ /** The refusal for a field a JavaScript caller passed that RunLabOptions no longer has. */
30
+ export function removedOptionRefusal(options) {
31
+ // rerun.laneIds, the older name of rerun.participantIds, would otherwise be ignored, so the rerun
32
+ // would select every failed participant instead of the ones the caller named.
33
+ if (options.rerun !== undefined && Reflect.get(options.rerun, "laneIds") !== undefined)
34
+ return {
35
+ ok: false,
36
+ code: "HUMANISH_LAB_OPTION_UNSUPPORTED",
37
+ message: 'RunLabOptions.rerun.laneIds was removed. Use rerun.participantIds. See docs/contracts/schemas.md, "Library options".',
38
+ };
39
+ const field = Object.keys(REMOVED_OPTIONS).find((key) => Reflect.get(options, key) !== undefined);
40
+ if (field === undefined)
41
+ return undefined;
42
+ return {
43
+ ok: false,
44
+ code: "HUMANISH_LAB_OPTION_UNSUPPORTED",
45
+ message: `RunLabOptions.${field} was removed. ${REMOVED_OPTIONS[field]} See docs/contracts/schemas.md, "Library options".`,
46
+ };
94
47
  }
95
48
  /** Why the route cannot honor an option it was given, or undefined when it can. */
96
49
  function unsupportedOption(config, route, options) {
@@ -113,11 +66,8 @@ function unsupportedOption(config, route, options) {
113
66
  if (prepareDesktop !== undefined) {
114
67
  if (isLocalBrowserLab(config))
115
68
  return unsupported("prepareDesktop", route, "a local VM study has no E2B desktop.");
116
- // The run is in process when either executor home is set: inProcess or the older
117
- // cuaHooks.buildExecutor. Either way no desktop exists to prepare.
118
- if (inProcess !== undefined ||
119
- hasMember(options.cuaHooks, "buildExecutor") ||
120
- source === "local-app")
69
+ // An in-process run has no desktop to prepare.
70
+ if (inProcess !== undefined || source === "local-app")
121
71
  return unsupported("prepareDesktop", route, "an in-process run has no desktop.");
122
72
  }
123
73
  return undefined;
@@ -133,200 +83,25 @@ function unsupportedOption(config, route, options) {
133
83
  : "this route has no E2B desktop to prepare.");
134
84
  }
135
85
  /**
136
- * Refuse what the route cannot honor, then map the new options into the old bags. Nothing here
137
- * touches the filesystem, so a refusal leaves no run directory, receipt or sandbox.
86
+ * Refuse what the route cannot honor, copy env, and build the emitter onEvent receives through.
87
+ * Nothing here touches the filesystem, so a refusal leaves no run directory, receipt or sandbox.
138
88
  */
139
89
  export function normalizeRunLabOptions(config, route, options) {
140
- const inUse = oldFieldsInUse(options);
141
- const clash = inUse.find((field) => field.clash);
142
- if (clash)
143
- return conflict(clash.home, clash.old);
144
90
  const refused = unsupportedOption(config, route, options);
145
91
  if (refused)
146
92
  return refused;
147
- for (const { home, old } of inUse)
148
- warnDeprecated(home, old);
149
- for (const old of retiredFieldsInUse(options))
150
- warnDeprecated(undefined, old);
151
93
  const warnings = [];
152
- const { env, scorer, prepareDesktop, onEvent, onStream, analysisSignal, createProvider, inProcess, ...legacy } = options;
94
+ const { env, onEvent, ...forwarded } = options;
153
95
  // The route gets this copy, so it is the env a warning is scrubbed against, whatever the caller
154
96
  // does to its own object afterwards.
155
97
  const forwardedEnv = env === undefined ? undefined : { ...env };
156
98
  const emit = labEventEmitter(onEvent, warnings, () => knownSecretValues(config, options, forwardedEnv));
157
- const normalized = { ...legacy };
158
- const participantIds = options.rerun?.participantIds;
159
- if (options.rerun !== undefined && participantIds !== undefined) {
160
- const { participantIds: _ids, ...rerun } = options.rerun;
161
- normalized.rerun = { ...rerun, laneIds: participantIds };
162
- }
163
- const analysis = withMapped(legacy.automaticAnalysis, HOOK_MEMBERS.analysis, {
164
- ...(analysisSignal === undefined
165
- ? {}
166
- : { deps: { ...legacy.automaticAnalysis?.deps, signal: analysisSignal } }),
167
- ...(emit === undefined
168
- ? {}
169
- : {
170
- onStart: () => {
171
- emit({ type: "analysis-started" });
172
- return () => emit({ type: "analysis-finished" });
173
- },
174
- }),
175
- });
176
- if (analysis !== undefined)
177
- normalized.automaticAnalysis = analysis;
178
- const envHome = forwardedEnv === undefined ? {} : { env: forwardedEnv };
179
- const scoring = scorer === undefined ? {} : scorerHooks(scorer);
180
- switch (route) {
181
- case "computer-use": {
182
- const hooks = withMapped(legacy.cuaHooks, HOOK_MEMBERS.cua, {
183
- ...envHome,
184
- ...scoring,
185
- ...computerUseHooks(config, {
186
- prepareDesktop,
187
- onStream,
188
- createProvider,
189
- inProcess,
190
- legacyInProcess: hasMember(legacy.cuaHooks, "buildExecutor"),
191
- }, emit),
192
- });
193
- if (hooks !== undefined)
194
- normalized.cuaHooks = hooks;
195
- break;
196
- }
197
- case "shared-world": {
198
- const hooks = withMapped(legacy.sharedWorldHooks, HOOK_MEMBERS.sharedWorld, {
199
- ...envHome,
200
- ...scoring,
201
- ...sharedWorldHooks({ prepareDesktop, onStream }, emit),
202
- });
203
- if (hooks !== undefined)
204
- normalized.sharedWorldHooks = hooks;
205
- break;
206
- }
207
- case "terminal": {
208
- const hooks = withMapped(legacy.terminalHooks, HOOK_MEMBERS.terminal, {
209
- ...envHome,
210
- ...(scorer?.score === undefined ? {} : { score: scorer.score }),
211
- ...(scorer?.deriveFeedback === undefined
212
- ? {}
213
- : { deriveFeedback: scorer.deriveFeedback }),
214
- });
215
- if (hooks !== undefined)
216
- normalized.terminalHooks = hooks;
217
- break;
218
- }
219
- case "scripted": {
220
- const hooks = withMapped(legacy.scriptedHooks, HOOK_MEMBERS.scripted, {
221
- ...envHome,
222
- ...(prepareDesktop === undefined
223
- ? {}
224
- : {
225
- prepareDesktop: (desktop) => prepareDesktop(desktop, { kind: "subject" }),
226
- }),
227
- });
228
- if (hooks !== undefined)
229
- normalized.scriptedHooks = hooks;
230
- break;
231
- }
232
- case "preview":
233
- break;
234
- }
235
- return { ok: true, options: normalized, warnings };
236
- }
237
- /** A caller's bag with new options mapped into it. With nothing to map, it is the same object. */
238
- function withMapped(bag, declared, mapped) {
239
- if (Object.keys(mapped).length === 0)
240
- return bag;
241
- return withHookOverrides(bag, declared, mapped);
242
- }
243
- export function scorerHooks(scorer) {
244
- return {
245
- ...(scorer.score === undefined ? {} : { score: scorer.score }),
246
- ...(scorer.deriveFeedback === undefined ? {} : { deriveFeedback: scorer.deriveFeedback }),
247
- ...(scorer.deriveArtifacts === undefined ? {} : { deriveArtifacts: scorer.deriveArtifacts }),
248
- };
249
- }
250
- /** The route awaits what these return, so onStream keeps the old hooks' barrier and errors. */
251
- function streamHooks(onStream) {
252
- return {
253
- onRuntimeStreamReady: (stream) => onStream({
254
- type: "ready",
255
- participantId: stream.laneId,
256
- sandboxId: stream.sandboxId,
257
- simId: stream.simId,
258
- streamId: stream.streamId,
259
- url: stream.url,
260
- }),
261
- onRuntimeStreamEnded: (stream) => onStream({
262
- type: "ended",
263
- participantId: stream.laneId,
264
- simId: stream.simId,
265
- streamId: stream.streamId,
266
- }),
267
- };
268
- }
269
- function computerUseHooks(config, homes, emit) {
270
- const { prepareDesktop, onStream, createProvider, inProcess, legacyInProcess } = homes;
271
- // A local VM study and an in-process run start no E2B stream, and the local study refuses a
272
- // stream hook outright, so onStream is left unset there: it is never called.
273
- const streams = !isLocalBrowserLab(config) && inProcess === undefined && !legacyInProcess;
274
- return {
275
- ...(prepareDesktop === undefined
276
- ? {}
277
- : {
278
- prepareDesktop: (desktop, participant) => prepareDesktop(desktop, {
279
- kind: "participant",
280
- participant: participantOf(participant),
281
- }),
282
- }),
283
- ...(createProvider === undefined
284
- ? {}
285
- : {
286
- buildProvider: ({ config: lab, lane: participant, laneCount, executor }) => createProvider({
287
- config: lab,
288
- participant: participantOf({ ...participant, laneCount }),
289
- executor,
290
- }),
291
- }),
292
- ...(inProcess === undefined
293
- ? {}
294
- : {
295
- buildExecutor: ({ config: lab, appUrl }) => inProcess.executor({ config: lab, appUrl }),
296
- }),
297
- ...(onStream !== undefined && streams ? streamHooks(onStream) : {}),
298
- ...(emit === undefined
299
- ? {}
300
- : {
301
- onPreflight: (plan) => emit(planEvent(plan)),
302
- onPhase: (event, participant) => {
303
- defaultSubjectPhaseSink(event, participant);
304
- emit(phaseEvent(event, { kind: "participant", participant: participantOf(participant) }));
305
- },
306
- }),
307
- };
308
- }
309
- function sharedWorldHooks(homes, emit) {
310
- const { prepareDesktop, onStream } = homes;
311
- return {
312
- ...(prepareDesktop === undefined
313
- ? {}
314
- : {
315
- // The provisioned plane prepares the subject sandbox with no participant, then each one.
316
- prepareDesktop: (desktop, participant) => prepareDesktop(desktop, participant === undefined
317
- ? { kind: "subject" }
318
- : { kind: "participant", participant: participantOf(participant) }),
319
- }),
320
- ...(onStream === undefined ? {} : streamHooks(onStream)),
321
- ...(emit === undefined
322
- ? {}
323
- : {
324
- onPhase: (event) => {
325
- defaultSharedWorldPhaseSink(event);
326
- emit(phaseEvent(event, { kind: "subject" }));
327
- },
328
- }),
329
- };
99
+ // Every route reads its typed options directly, and onEvent reaches it as `emit`. unsupportedOption
100
+ // already refused an option no route reads; the preview route reads no env.
101
+ const normalized = { ...forwarded };
102
+ if (route !== "preview" && forwardedEnv !== undefined)
103
+ normalized.env = forwardedEnv;
104
+ return { ok: true, options: normalized, warnings, emit };
330
105
  }
331
106
  /** A refusal in the route's own result envelope, before any run exists. */
332
107
  export function optionRefusalOutcome(config, route, options, refusal) {
@@ -340,13 +115,11 @@ export function optionRefusalOutcome(config, route, options, refusal) {
340
115
  case "preview":
341
116
  return {
342
117
  route: "preview",
343
- backend: "synthetic",
344
118
  result: { schema: "humanish.run-result.v1", ok: false, cwd, warnings: [], error },
345
119
  };
346
120
  case "computer-use":
347
121
  return {
348
122
  route: "computer-use",
349
- backend: "cua",
350
123
  result: {
351
124
  schema: CUA_ACTOR_LAB_SCHEMA,
352
125
  ...common,
@@ -358,7 +131,6 @@ export function optionRefusalOutcome(config, route, options, refusal) {
358
131
  case "scripted":
359
132
  return {
360
133
  route: "scripted",
361
- backend: "scripted",
362
134
  result: {
363
135
  schema: SCRIPTED_BROWSER_LAB_SCHEMA,
364
136
  ...common,
@@ -370,7 +142,6 @@ export function optionRefusalOutcome(config, route, options, refusal) {
370
142
  case "terminal":
371
143
  return {
372
144
  route: "terminal",
373
- backend: "terminal",
374
145
  result: {
375
146
  schema: TERMINAL_PRODUCT_LAB_SCHEMA,
376
147
  ...common,
@@ -382,7 +153,6 @@ export function optionRefusalOutcome(config, route, options, refusal) {
382
153
  const participantCount = rosterOf(config.actors[0])?.length ?? 0;
383
154
  return {
384
155
  route: "shared-world",
385
- backend: "concurrent-shared-world",
386
156
  result: {
387
157
  schema: CONCURRENT_SHARED_WORLD_LAB_SCHEMA,
388
158
  ...common,
@@ -2,9 +2,9 @@ import { type LocalRuntimeStatus } from "../substrates/local/runtime.js";
2
2
  import { type KeyResolutionDeps } from "../keys/key-resolution.js";
3
3
  export declare const LAB_SUMMARY_SCHEMA = "humanish.lab-summary.v1";
4
4
  export interface LabCaps {
5
- /** Per-lane blast-radius budget. */
5
+ /** Per-participant blast-radius budget. */
6
6
  laneUsd?: number;
7
- /** Shared study budget across every lane. */
7
+ /** Shared study budget across every participant. */
8
8
  studyUsd?: number;
9
9
  }
10
10
  export interface LabSummary {
@@ -31,8 +31,8 @@ export interface LabSummary {
31
31
  /** The model that will actually run, override or default. */
32
32
  model?: string;
33
33
  /**
34
- * The reasoning effort that will actually run, override or default — and "per-lane" when the
35
- * roster declares more than one, because a single value would be a lie about half the lanes.
34
+ * The reasoning effort that will actually run, override or default — and `"per-lane"` when the
35
+ * roster declares more than one, because a single value would be a lie about half the participants.
36
36
  *
37
37
  * Shown because it was a silent constant: unreachable from a lab, so every run took the provider
38
38
  * default. A study variable you cannot see is one nobody chose (#497).
@@ -45,6 +45,11 @@ export interface LabSummary {
45
45
  */
46
46
  keysReady?: boolean;
47
47
  missingKeys?: string[];
48
+ /**
49
+ * The planner's refusal message when a live key check finds the lab will not plan, as
50
+ * `humanish lab run` would report it. `keysReady` is then unset: a refused plan lists no keys.
51
+ */
52
+ planRefusal?: string;
48
53
  }
49
54
  export interface ReadLabSummaryOptions {
50
55
  /** Skip the key probe (it touches vendor stores); the screen then shows no keys line. */
@@ -10,7 +10,8 @@ import { localRuntimeStatus } from "../substrates/local/runtime.js";
10
10
  // declared is not "unlimited" and not "$0"; it is a line the screen does not draw.
11
11
  import { resolveLabDryRun } from "./plan.js";
12
12
  import { routeOf } from "./plan.js";
13
- import { labKeyRequirements, localCodexParticipantCheck } from "./doctor.js";
13
+ import { localCodexParticipantCheck, planCliRun } from "./doctor.js";
14
+ import { requiredKeys, requiredSubjectEnv } from "./requirements.js";
14
15
  import { automaticAnalysisBudget } from "../analysis/automatic-config.js";
15
16
  import { DEFAULT_OPENAI_CU_MODEL, DEFAULT_OPENAI_CU_REASONING_EFFORT, } from "../actors/computer-use/openai-provider.js";
16
17
  import { inspectLabManifest } from "./discover.js";
@@ -20,7 +21,7 @@ import { receivingRequiredKey } from "../comms/setup.js";
20
21
  import { rosterOf } from "./parse/actors.js";
21
22
  export const LAB_SUMMARY_SCHEMA = "humanish.lab-summary.v1";
22
23
  /**
23
- * The effort every lane will run at, or "per-lane" when they differ. A lane that declares nothing
24
+ * The effort every participant will run at, or `"per-lane"` when they differ. A participant that declares nothing
24
25
  * inherits the actor's, and an actor that declares nothing gets the provider default — which is
25
26
  * reported as the resolved value, exactly as `model` reports its default rather than hiding it.
26
27
  */
@@ -60,7 +61,7 @@ function participantsOf(config) {
60
61
  const unique = [...new Set(personas)];
61
62
  if (unique.length === 0)
62
63
  return `${count} participant${count === 1 ? "" : "s"}`;
63
- // Several lanes of ONE persona reads as "3 × skeptical-power-user"; genuinely different people
64
+ // Several participants of ONE persona reads as "3 × skeptical-power-user"; genuinely different people
64
65
  // are named, because which personas are in a study is the study's design.
65
66
  return unique.length === 1 ? `${count} × ${unique[0]}` : unique.join(" · ");
66
67
  }
@@ -87,9 +88,14 @@ export async function readLabSummary(cwd, lab, options = {}) {
87
88
  const route = routeOf(inspected.config);
88
89
  let keysReady;
89
90
  let missingKeys;
90
- if (options.checkKeys === true) {
91
- const dryRun = resolveLabDryRun(inspected.config, undefined, true) === true;
92
- const subjectKeys = dryRun ? [] : (inspected.config.subject.env ?? []);
91
+ const dryRun = resolveLabDryRun(inspected.config, undefined, true) === true;
92
+ // A live key check reads the plan's requirements. A lab the planner refuses has none to check,
93
+ // so the summary reports the refusal in place of its keys.
94
+ const planned = options.checkKeys === true && !dryRun ? await planCliRun(inspected.config, cwd) : undefined;
95
+ const planRefusal = planned?.ok === false ? planned.refusal.message : undefined;
96
+ if (options.checkKeys === true && planned?.ok !== false) {
97
+ const requirements = planned?.planned.plan.requirements ?? [];
98
+ const subjectKeys = requiredSubjectEnv(requirements);
93
99
  const email = inspected.config.comms?.email;
94
100
  const receivingKey = !dryRun && email?.kind === "real"
95
101
  ? await receivingRequiredKey(cwd, email.connection)
@@ -109,9 +115,9 @@ export async function readLabSummary(cwd, lab, options = {}) {
109
115
  ...(options.keyDeps === undefined ? {} : { deps: options.keyDeps }),
110
116
  }).catch(() => []);
111
117
  const present = new Set(probes.filter((probe) => probe.source !== null).map((probe) => probe.name));
112
- const required = labKeyRequirements(inspected.config, route, dryRun, (name) => present.has(name));
118
+ const required = requiredKeys(requirements, (name) => present.has(name));
113
119
  const missing = [
114
- ...new Set([...required.keys, ...subjectKeys, ...(receivingKey ? [receivingKey] : [])]),
120
+ ...new Set([...required, ...subjectKeys, ...(receivingKey ? [receivingKey] : [])]),
115
121
  ].filter((name) => !present.has(name));
116
122
  if (receivingKey === null)
117
123
  missing.push("email connection");
@@ -164,5 +170,6 @@ export async function readLabSummary(cwd, lab, options = {}) {
164
170
  caps: capsOf(inspected.config),
165
171
  ...(keysReady === undefined ? {} : { keysReady }),
166
172
  ...(missingKeys === undefined ? {} : { missingKeys }),
173
+ ...(planRefusal === undefined ? {} : { planRefusal }),
167
174
  };
168
175
  }