humanish 0.108.0 → 0.109.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 (455) hide show
  1. package/ARCHITECTURE.md +58 -59
  2. package/CHANGELOG.md +13 -0
  3. package/CONTEXT.md +44 -44
  4. package/README.md +3 -3
  5. package/TELEMETRY.md +2 -2
  6. package/dist/actors/codex/app-server-trace.js +2 -1
  7. package/dist/actors/codex/restricted-participant.js +12 -12
  8. package/dist/actors/codex/restricted-session.d.ts +2 -2
  9. package/dist/actors/computer-use/actor.d.ts +6 -6
  10. package/dist/actors/computer-use/actor.js +2 -2
  11. package/dist/actors/computer-use/admission-limit.d.ts +2 -2
  12. package/dist/actors/computer-use/admission-limit.js +3 -3
  13. package/dist/actors/computer-use/executor-error.d.ts +2 -2
  14. package/dist/actors/computer-use/executor-error.js +3 -3
  15. package/dist/actors/computer-use/loop/actions.js +5 -5
  16. package/dist/actors/computer-use/loop/debrief.js +2 -2
  17. package/dist/actors/computer-use/loop/ending.d.ts +1 -1
  18. package/dist/actors/computer-use/loop/ending.js +12 -11
  19. package/dist/actors/computer-use/loop/observation.js +6 -5
  20. package/dist/actors/computer-use/loop/provider-call.js +11 -11
  21. package/dist/actors/computer-use/loop/session.d.ts +4 -4
  22. package/dist/actors/computer-use/loop/session.js +2 -2
  23. package/dist/actors/computer-use/loop/trace.js +3 -2
  24. package/dist/actors/computer-use/loop/types.d.ts +24 -24
  25. package/dist/actors/computer-use/loop/usage.d.ts +2 -2
  26. package/dist/actors/computer-use/loop.d.ts +6 -1
  27. package/dist/actors/computer-use/loop.js +26 -4
  28. package/dist/actors/computer-use/openai-provider.d.ts +2 -2
  29. package/dist/actors/computer-use/openai-provider.js +8 -8
  30. package/dist/actors/computer-use/provider-error.d.ts +4 -4
  31. package/dist/actors/computer-use/provider-error.js +6 -6
  32. package/dist/actors/contract.d.ts +4 -4
  33. package/dist/actors/contract.js +1 -1
  34. package/dist/actors/local-agent/claude-session.js +3 -3
  35. package/dist/actors/local-agent/cli.d.ts +1 -1
  36. package/dist/actors/local-agent/cli.js +1 -1
  37. package/dist/actors/reasoning-effort.js +3 -3
  38. package/dist/actors/registry.d.ts +2 -2
  39. package/dist/actors/registry.js +3 -3
  40. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  41. package/dist/actors/scripted-browser/actor.js +1 -1
  42. package/dist/analysis/automatic-completion.d.ts +7 -7
  43. package/dist/analysis/automatic-completion.js +1 -1
  44. package/dist/analysis/automatic-config.d.ts +6 -6
  45. package/dist/analysis/automatic-config.js +1 -1
  46. package/dist/analysis/execute.d.ts +1 -1
  47. package/dist/analysis/execute.js +1 -1
  48. package/dist/analysis/types.d.ts +6 -0
  49. package/dist/browser-control/client.js +16 -16
  50. package/dist/browser-control/dispatcher.js +4 -4
  51. package/dist/browser-control/protocol.js +14 -14
  52. package/dist/browser-control/recording-transfer.js +4 -4
  53. package/dist/browser-control/transport.js +7 -7
  54. package/dist/cli/commands/analysis-signals.d.ts +2 -2
  55. package/dist/cli/commands/comms.js +14 -22
  56. package/dist/cli/commands/observe.d.ts +0 -1
  57. package/dist/cli/commands/observe.js +0 -15
  58. package/dist/cli/commands/run-command.d.ts +2 -2
  59. package/dist/cli/commands/run-command.js +3 -3
  60. package/dist/cli/commands/runs.js +3 -5
  61. package/dist/cli/commands/setup.js +5 -7
  62. package/dist/cli/commands/study-format.d.ts +9 -0
  63. package/dist/cli/commands/{lab-format.js → study-format.js} +5 -5
  64. package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
  65. package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +12 -12
  66. package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
  67. package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
  68. package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
  69. package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +3 -3
  70. package/dist/cli/commands/study-route-run.d.ts +19 -0
  71. package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
  72. package/dist/cli/commands/study-route-scripted.d.ts +17 -0
  73. package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
  74. package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
  75. package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +7 -7
  76. package/dist/cli/commands/study-route-terminal.d.ts +17 -0
  77. package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
  78. package/dist/cli/commands/study-run.d.ts +9 -0
  79. package/dist/cli/commands/{lab-run.js → study-run.js} +34 -34
  80. package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +5 -5
  81. package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +1 -1
  82. package/dist/cli/commands/study.js +13 -49
  83. package/dist/cli/commands/tui.js +12 -12
  84. package/dist/cli/commands/watch.js +30 -65
  85. package/dist/cli/deprecations.d.ts +1 -13
  86. package/dist/cli/deprecations.js +0 -30
  87. package/dist/cli/doctor.d.ts +3 -3
  88. package/dist/cli/doctor.js +16 -16
  89. package/dist/cli/first-run-path.d.ts +4 -4
  90. package/dist/cli/first-run-path.js +7 -7
  91. package/dist/cli/io.d.ts +3 -3
  92. package/dist/cli/io.js +2 -2
  93. package/dist/cli/observer-follow.d.ts +2 -2
  94. package/dist/cli/observer-follow.js +2 -2
  95. package/dist/cli/orientation.d.ts +4 -4
  96. package/dist/cli/orientation.js +58 -20
  97. package/dist/cli/program.js +3 -4
  98. package/dist/cli/telemetry.d.ts +1 -1
  99. package/dist/cli/telemetry.js +14 -20
  100. package/dist/comms/catch-host.d.ts +1 -1
  101. package/dist/comms/catch-host.js +3 -3
  102. package/dist/comms/connections.d.ts +1 -1
  103. package/dist/comms/connections.js +2 -2
  104. package/dist/comms/external-evidence.d.ts +5 -5
  105. package/dist/comms/external-evidence.js +4 -3
  106. package/dist/comms/fake-inbox.d.ts +2 -2
  107. package/dist/comms/fake-inbox.js +2 -2
  108. package/dist/comms/receiving-runtime.d.ts +4 -4
  109. package/dist/comms/sandbox-catch.d.ts +2 -2
  110. package/dist/comms/sandbox-catch.js +2 -2
  111. package/dist/comms/setup.d.ts +2 -2
  112. package/dist/comms/setup.js +29 -32
  113. package/dist/feedback/draft.js +2 -2
  114. package/dist/feedback/export.js +3 -2
  115. package/dist/feedback/proof.d.ts +1 -1
  116. package/dist/feedback/proof.js +2 -2
  117. package/dist/guest/bootstrap.js +6 -6
  118. package/dist/guest/browser-tools.js +8 -8
  119. package/dist/guest/chromium-text.js +17 -17
  120. package/dist/guest/desktop-executor.d.ts +2 -2
  121. package/dist/guest/desktop-executor.js +20 -20
  122. package/dist/guest/desktop-keys.js +4 -4
  123. package/dist/guest/desktop-media.d.ts +2 -2
  124. package/dist/guest/desktop-media.js +16 -16
  125. package/dist/guest/desktop-native.js +10 -10
  126. package/dist/guest/runtime-desktop.js +2 -2
  127. package/dist/guest/runtime-processes.d.ts +2 -2
  128. package/dist/guest/runtime-processes.js +2 -2
  129. package/dist/guest/runtime.js +5 -5
  130. package/dist/index.d.ts +13 -15
  131. package/dist/index.js +6 -8
  132. package/dist/observer/artifact.d.ts +1 -1
  133. package/dist/observer/artifact.js +1 -1
  134. package/dist/observer/data.d.ts +1 -1
  135. package/dist/observer/library.d.ts +2 -0
  136. package/dist/observer/library.js +4 -1
  137. package/dist/observer/render.js +7 -1
  138. package/dist/observer/run-routes.d.ts +1 -0
  139. package/dist/observer/run-routes.js +37 -12
  140. package/dist/observer/serve.d.ts +1 -1
  141. package/dist/observer-app.html +1 -1
  142. package/dist/routes/computer-use/bundle-parts.js +3 -2
  143. package/dist/routes/computer-use/bundle.d.ts +2 -2
  144. package/dist/routes/computer-use/bundle.js +7 -6
  145. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +5 -5
  146. package/dist/routes/computer-use/e2b-desktop/comms.js +5 -4
  147. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +1 -1
  148. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
  149. package/dist/routes/computer-use/e2b-desktop/prepare.js +3 -3
  150. package/dist/routes/computer-use/e2b-desktop/start.js +3 -4
  151. package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
  152. package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -3
  153. package/dist/routes/computer-use/external-comms.d.ts +3 -3
  154. package/dist/routes/computer-use/fanout-bundle.js +11 -10
  155. package/dist/routes/computer-use/fanout-records.js +2 -2
  156. package/dist/routes/computer-use/live-flush.d.ts +3 -3
  157. package/dist/routes/computer-use/live-phase.d.ts +2 -3
  158. package/dist/routes/computer-use/live-phase.js +3 -3
  159. package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
  160. package/dist/routes/computer-use/local-tree-pack.js +1 -1
  161. package/dist/routes/computer-use/local-vm.d.ts +8 -8
  162. package/dist/routes/computer-use/local-vm.js +2 -2
  163. package/dist/routes/computer-use/participant-desktop.d.ts +3 -3
  164. package/dist/routes/computer-use/participant-desktop.js +1 -1
  165. package/dist/routes/computer-use/participant-execution.js +1 -1
  166. package/dist/routes/computer-use/participant-model.js +3 -3
  167. package/dist/routes/computer-use/participant-prompt.d.ts +5 -5
  168. package/dist/routes/computer-use/participant-prompt.js +3 -3
  169. package/dist/routes/computer-use/participant-runs.d.ts +10 -10
  170. package/dist/routes/computer-use/participant-runs.js +14 -13
  171. package/dist/routes/computer-use/plan.d.ts +12 -12
  172. package/dist/routes/computer-use/plan.js +24 -24
  173. package/dist/routes/computer-use/preflight.d.ts +5 -5
  174. package/dist/routes/computer-use/preflight.js +5 -5
  175. package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
  176. package/dist/routes/computer-use/rerun-selection.js +3 -2
  177. package/dist/routes/computer-use/result.d.ts +4 -4
  178. package/dist/routes/computer-use/result.js +13 -12
  179. package/dist/routes/computer-use/route.d.ts +12 -12
  180. package/dist/routes/computer-use/route.js +19 -19
  181. package/dist/routes/computer-use/self-report.js +1 -1
  182. package/dist/routes/computer-use/setup.d.ts +22 -22
  183. package/dist/routes/computer-use/setup.js +15 -15
  184. package/dist/routes/computer-use/single-bundle.d.ts +4 -4
  185. package/dist/routes/computer-use/single-bundle.js +14 -13
  186. package/dist/routes/computer-use/subject-projection.d.ts +3 -3
  187. package/dist/routes/computer-use/types.d.ts +34 -34
  188. package/dist/routes/computer-use/types.js +3 -3
  189. package/dist/routes/preview.d.ts +6 -6
  190. package/dist/routes/preview.js +5 -5
  191. package/dist/routes/scripted/bundle.d.ts +6 -6
  192. package/dist/routes/scripted/bundle.js +10 -9
  193. package/dist/routes/scripted/plan.d.ts +7 -7
  194. package/dist/routes/scripted/plan.js +6 -6
  195. package/dist/routes/scripted/result.d.ts +3 -3
  196. package/dist/routes/scripted/result.js +9 -9
  197. package/dist/routes/scripted/route.d.ts +9 -9
  198. package/dist/routes/scripted/route.js +11 -11
  199. package/dist/routes/scripted/scenario.d.ts +1 -1
  200. package/dist/routes/scripted/scenario.js +3 -3
  201. package/dist/routes/scripted/setup.d.ts +6 -6
  202. package/dist/routes/scripted/setup.js +4 -4
  203. package/dist/routes/scripted/subject.d.ts +5 -5
  204. package/dist/routes/scripted/subject.js +3 -3
  205. package/dist/routes/scripted/surface-records.d.ts +1 -1
  206. package/dist/routes/scripted/surface-records.js +2 -2
  207. package/dist/routes/scripted/surface-sessions.d.ts +3 -3
  208. package/dist/routes/scripted/types.d.ts +17 -17
  209. package/dist/routes/scripted/types.js +1 -1
  210. package/dist/routes/shared-world/bundle-records.js +3 -3
  211. package/dist/routes/shared-world/bundle.js +15 -14
  212. package/dist/routes/shared-world/checkpoints.d.ts +3 -3
  213. package/dist/routes/shared-world/checkpoints.js +1 -1
  214. package/dist/routes/shared-world/comms.d.ts +9 -9
  215. package/dist/routes/shared-world/comms.js +6 -5
  216. package/dist/routes/shared-world/participant-specs.d.ts +3 -3
  217. package/dist/routes/shared-world/participant-specs.js +7 -7
  218. package/dist/routes/shared-world/plan.d.ts +9 -9
  219. package/dist/routes/shared-world/plan.js +9 -9
  220. package/dist/routes/shared-world/provisioned.d.ts +8 -8
  221. package/dist/routes/shared-world/provisioned.js +4 -4
  222. package/dist/routes/shared-world/result.d.ts +6 -6
  223. package/dist/routes/shared-world/result.js +11 -10
  224. package/dist/routes/shared-world/route.d.ts +11 -11
  225. package/dist/routes/shared-world/route.js +19 -19
  226. package/dist/routes/shared-world/setup.d.ts +13 -13
  227. package/dist/routes/shared-world/setup.js +19 -19
  228. package/dist/routes/shared-world/types.d.ts +27 -27
  229. package/dist/routes/terminal/adapter.d.ts +2 -2
  230. package/dist/routes/terminal/adapter.js +4 -4
  231. package/dist/routes/terminal/bundle.d.ts +11 -11
  232. package/dist/routes/terminal/bundle.js +12 -12
  233. package/dist/routes/terminal/credentials.d.ts +4 -4
  234. package/dist/routes/terminal/credentials.js +5 -5
  235. package/dist/routes/terminal/dry-run.d.ts +4 -4
  236. package/dist/routes/terminal/dry-run.js +9 -9
  237. package/dist/routes/terminal/ledger.d.ts +2 -2
  238. package/dist/routes/terminal/lifetime.d.ts +1 -1
  239. package/dist/routes/terminal/lifetime.js +1 -1
  240. package/dist/routes/terminal/live-finish.d.ts +2 -2
  241. package/dist/routes/terminal/live-finish.js +7 -7
  242. package/dist/routes/terminal/live-sandbox.d.ts +2 -2
  243. package/dist/routes/terminal/live-sandbox.js +3 -2
  244. package/dist/routes/terminal/participant-text.js +2 -1
  245. package/dist/routes/terminal/persona.d.ts +2 -2
  246. package/dist/routes/terminal/persona.js +2 -2
  247. package/dist/routes/terminal/plan.d.ts +7 -7
  248. package/dist/routes/terminal/plan.js +5 -5
  249. package/dist/routes/terminal/result.d.ts +5 -5
  250. package/dist/routes/terminal/result.js +7 -7
  251. package/dist/routes/terminal/route.d.ts +9 -9
  252. package/dist/routes/terminal/route.js +14 -14
  253. package/dist/routes/terminal/session.d.ts +5 -5
  254. package/dist/routes/terminal/session.js +7 -7
  255. package/dist/routes/terminal/trace.d.ts +2 -2
  256. package/dist/routes/terminal/types.d.ts +24 -24
  257. package/dist/routes/terminal/types.js +2 -2
  258. package/dist/run/bundle.d.ts +7 -7
  259. package/dist/run/bundle.js +2 -2
  260. package/dist/run/costs.d.ts +23 -0
  261. package/dist/run/costs.js +72 -43
  262. package/dist/run/dry-run-inputs.d.ts +1 -1
  263. package/dist/run/dry-run-inputs.js +1 -1
  264. package/dist/run/dry-run.js +2 -2
  265. package/dist/run/outcomes.d.ts +1 -1
  266. package/dist/run/participant.d.ts +1 -1
  267. package/dist/run/preflight-receipts.js +1 -1
  268. package/dist/run/pricing.js +2 -2
  269. package/dist/run/projection.d.ts +32 -32
  270. package/dist/run/projection.js +44 -44
  271. package/dist/run/reclaim.d.ts +1 -1
  272. package/dist/run/reclaim.js +1 -1
  273. package/dist/run/results.d.ts +2 -2
  274. package/dist/run/run-cost.d.ts +53 -0
  275. package/dist/run/run-cost.js +105 -0
  276. package/dist/run/run-index-analysis.d.ts +15 -0
  277. package/dist/run/run-index-analysis.js +77 -0
  278. package/dist/run/run-index.d.ts +11 -1
  279. package/dist/run/run-index.js +63 -49
  280. package/dist/run/run.d.ts +3 -3
  281. package/dist/run/run.js +2 -2
  282. package/dist/run/shared-world-evidence.d.ts +1 -1
  283. package/dist/run/shared-world-shape.js +1 -1
  284. package/dist/run/stats.d.ts +3 -3
  285. package/dist/run/stats.js +14 -14
  286. package/dist/run/status.d.ts +10 -2
  287. package/dist/run/status.js +6 -3
  288. package/dist/run/streams.d.ts +2 -2
  289. package/dist/run/study-provenance.d.ts +4 -2
  290. package/dist/run/study-provenance.js +7 -4
  291. package/dist/run/study-result.d.ts +0 -5
  292. package/dist/run/study-result.js +1 -1
  293. package/dist/run-study.d.ts +112 -0
  294. package/dist/{run-lab.js → run-study.js} +52 -45
  295. package/dist/{lab → study}/adapter-extension.d.ts +8 -20
  296. package/dist/{lab → study}/adapter-extension.js +2 -14
  297. package/dist/{lab → study}/adapter-scorer-loader.d.ts +10 -10
  298. package/dist/{lab → study}/adapter-scorer-loader.js +3 -3
  299. package/dist/study/composition-rules.d.ts +7 -0
  300. package/dist/{lab → study}/composition-rules.js +12 -12
  301. package/dist/study/config.d.ts +15 -0
  302. package/dist/{lab → study}/config.js +37 -20
  303. package/dist/study/convert.d.ts +1 -1
  304. package/dist/study/convert.js +15 -15
  305. package/dist/{lab → study}/device-presets.d.ts +2 -2
  306. package/dist/{lab → study}/discover.d.ts +29 -23
  307. package/dist/{lab → study}/discover.js +97 -118
  308. package/dist/{lab → study}/doctor.d.ts +11 -11
  309. package/dist/{lab → study}/doctor.js +18 -18
  310. package/dist/study/files.d.ts +2 -2
  311. package/dist/study/files.js +6 -5
  312. package/dist/{lab → study}/init-templates.d.ts +2 -2
  313. package/dist/{lab → study}/init-templates.js +16 -11
  314. package/dist/{lab → study}/init.d.ts +1 -1
  315. package/dist/{lab → study}/init.js +7 -4
  316. package/dist/{lab → study}/keys.d.ts +2 -2
  317. package/dist/{lab → study}/keys.js +10 -10
  318. package/dist/study/migrate.d.ts +1 -1
  319. package/dist/{lab → study}/parse/actors.d.ts +5 -5
  320. package/dist/{lab → study}/parse/actors.js +5 -5
  321. package/dist/study/parse/comms.d.ts +12 -0
  322. package/dist/study/parse/execution.d.ts +19 -0
  323. package/dist/{lab → study}/parse/study-v3.d.ts +3 -5
  324. package/dist/{lab → study}/parse/study-v3.js +3 -3
  325. package/dist/{lab → study}/parse/subject-state.d.ts +8 -8
  326. package/dist/{lab → study}/parse/subject-state.js +4 -4
  327. package/dist/{lab → study}/parse/subject.d.ts +3 -3
  328. package/dist/{lab → study}/parse/subject.js +8 -8
  329. package/dist/{lab → study}/parse/values.d.ts +2 -2
  330. package/dist/{lab → study}/persona-resolve.d.ts +4 -4
  331. package/dist/{lab → study}/persona-resolve.js +2 -2
  332. package/dist/{lab → study}/plan-base.d.ts +7 -7
  333. package/dist/{lab → study}/plan-base.js +1 -1
  334. package/dist/{lab → study}/plan-participants.d.ts +10 -10
  335. package/dist/{lab → study}/plan-participants.js +4 -4
  336. package/dist/{lab → study}/plan-types.d.ts +28 -28
  337. package/dist/{lab → study}/plan-types.js +2 -2
  338. package/dist/study/plan.d.ts +13 -0
  339. package/dist/{lab → study}/plan.js +20 -20
  340. package/dist/study/preflight-probes.d.ts +3 -0
  341. package/dist/{lab → study}/preflight-probes.js +9 -8
  342. package/dist/study/preflight-result.d.ts +8 -0
  343. package/dist/{lab → study}/preflight-result.js +3 -3
  344. package/dist/{lab → study}/preflight.d.ts +31 -31
  345. package/dist/{lab → study}/preflight.js +8 -8
  346. package/dist/{lab → study}/requirements.d.ts +3 -3
  347. package/dist/{lab → study}/requirements.js +1 -1
  348. package/dist/study/route-inputs.d.ts +28 -0
  349. package/dist/{lab → study}/route-inputs.js +1 -1
  350. package/dist/{lab → study}/routing.d.ts +12 -12
  351. package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -10
  352. package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -3
  353. package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +8 -17
  354. package/dist/study/run-study-homes.js +3 -0
  355. package/dist/study/run-study-options.d.ts +28 -0
  356. package/dist/{lab/run-lab-options.js → study/run-study-options.js} +13 -12
  357. package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +2 -2
  358. package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
  359. package/dist/{lab → study}/summary.d.ts +10 -10
  360. package/dist/{lab → study}/summary.js +15 -15
  361. package/dist/{lab → study}/tasks.d.ts +3 -3
  362. package/dist/{lab → study}/tasks.js +1 -1
  363. package/dist/{lab → study}/types.d.ts +104 -104
  364. package/dist/{lab → study}/types.js +1 -1
  365. package/dist/{lab → study}/validation.d.ts +19 -19
  366. package/dist/{lab → study}/validation.js +13 -13
  367. package/dist/{lab → study}/warnings.d.ts +4 -4
  368. package/dist/{lab → study}/warnings.js +1 -1
  369. package/dist/subject/clone.d.ts +6 -6
  370. package/dist/subject/clone.js +2 -2
  371. package/dist/subject/local-tree-archive.d.ts +2 -2
  372. package/dist/subject/local-tree-archive.js +3 -3
  373. package/dist/subject/local-tree.d.ts +3 -3
  374. package/dist/subject/runtime.js +2 -2
  375. package/dist/subject/serve.d.ts +4 -4
  376. package/dist/subject/state.d.ts +3 -3
  377. package/dist/subject/state.js +1 -1
  378. package/dist/subject/steps.d.ts +1 -1
  379. package/dist/subject/steps.js +1 -1
  380. package/dist/substrates/desktop-session.js +2 -2
  381. package/dist/substrates/detached.d.ts +1 -1
  382. package/dist/substrates/e2b/desktop-browser.d.ts +4 -4
  383. package/dist/substrates/e2b/desktop-browser.js +1 -1
  384. package/dist/substrates/e2b/desktop-cdp.d.ts +1 -1
  385. package/dist/substrates/e2b/desktop-cdp.js +1 -1
  386. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  387. package/dist/substrates/e2b/desktop-executor.js +12 -12
  388. package/dist/substrates/e2b/desktop-geometry.d.ts +1 -1
  389. package/dist/substrates/e2b/desktop-geometry.js +1 -1
  390. package/dist/substrates/e2b/desktop-media.d.ts +3 -3
  391. package/dist/substrates/e2b/lifetime.js +1 -1
  392. package/dist/substrates/e2b/sandbox.d.ts +3 -3
  393. package/dist/substrates/e2b/sandbox.js +1 -1
  394. package/dist/substrates/e2b/sdk.d.ts +1 -1
  395. package/dist/substrates/e2b/sdk.js +1 -1
  396. package/dist/substrates/local/runtime-config.d.ts +4 -4
  397. package/dist/substrates/local/runtime-config.js +4 -4
  398. package/dist/tui/contract.d.ts +8 -8
  399. package/dist/tui/contract.js +2 -2
  400. package/dist/tui/launch.d.ts +3 -3
  401. package/dist/tui/launch.js +22 -16
  402. package/dist/tui-app.js +139 -139
  403. package/dist/verify/subject.d.ts +1 -1
  404. package/dist/verify/subject.js +1 -1
  405. package/dist/verify/verify.js +2 -1
  406. package/docs/architecture/actor-contract.md +5 -5
  407. package/docs/architecture/browser-control.md +1 -1
  408. package/docs/architecture/external-public-shared-world.md +8 -7
  409. package/docs/architecture/github-feedback-loop.md +1 -1
  410. package/docs/architecture/task-protocol-support.md +1 -1
  411. package/docs/architecture/terminal-product-route.md +18 -18
  412. package/docs/contracts/adapter-fixtures.md +2 -2
  413. package/docs/contracts/errors.md +8 -8
  414. package/docs/contracts/run-bundle.md +1 -4
  415. package/docs/contracts/schemas.md +61 -42
  416. package/docs/contracts/study-analysis.md +4 -1
  417. package/docs/contracts/study-costs.md +17 -2
  418. package/examples/README.md +1 -1
  419. package/examples/scorer/scorer.mjs +3 -3
  420. package/package.json +1 -1
  421. package/skills/humanish/SKILL.md +8 -6
  422. package/skills/humanish/agents/openai.yaml +1 -1
  423. package/dist/cli/commands/lab-format.d.ts +0 -9
  424. package/dist/cli/commands/lab-route-run.d.ts +0 -19
  425. package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
  426. package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
  427. package/dist/cli/commands/lab-run.d.ts +0 -9
  428. package/dist/lab/composition-rules.d.ts +0 -7
  429. package/dist/lab/config.d.ts +0 -7
  430. package/dist/lab/deprecated-fields.d.ts +0 -10
  431. package/dist/lab/deprecated-fields.js +0 -24
  432. package/dist/lab/parse/comms.d.ts +0 -12
  433. package/dist/lab/parse/execution.d.ts +0 -19
  434. package/dist/lab/plan.d.ts +0 -13
  435. package/dist/lab/preflight-probes.d.ts +0 -3
  436. package/dist/lab/preflight-result.d.ts +0 -8
  437. package/dist/lab/route-inputs.d.ts +0 -28
  438. package/dist/lab/run-lab-homes.js +0 -7
  439. package/dist/lab/run-lab-options.d.ts +0 -28
  440. package/dist/library-aliases.d.ts +0 -56
  441. package/dist/library-aliases.js +0 -22
  442. package/dist/run-lab.d.ts +0 -112
  443. /package/dist/{lab → study}/device-presets.js +0 -0
  444. /package/dist/{lab → study}/init-paths.d.ts +0 -0
  445. /package/dist/{lab → study}/init-paths.js +0 -0
  446. /package/dist/{lab → study}/init-plan.d.ts +0 -0
  447. /package/dist/{lab → study}/init-plan.js +0 -0
  448. /package/dist/{lab → study}/parse/comms.js +0 -0
  449. /package/dist/{lab → study}/parse/execution.js +0 -0
  450. /package/dist/{lab → study}/parse/values.js +0 -0
  451. /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
  452. /package/dist/{lab → study}/participant-assignment.js +0 -0
  453. /package/dist/{lab → study}/persona.d.ts +0 -0
  454. /package/dist/{lab → study}/persona.js +0 -0
  455. /package/dist/{lab → study}/routing.js +0 -0
@@ -1,8 +1,9 @@
1
+ import { DEFAULT_ANALYSIS_MAX_COST_USD } from "../analysis/automatic-config.js";
1
2
  export const DEFAULT_LOCAL_BROWSER_STARTER = {
2
3
  appUrl: "http://127.0.0.1:3000",
3
4
  mission: "Use the app's primary flow. Explain anything confusing and stop when the task is complete or you are stuck.",
4
5
  };
5
- function localBrowserLab(starter = DEFAULT_LOCAL_BROWSER_STARTER) {
6
+ function localBrowserStudy(starter = DEFAULT_LOCAL_BROWSER_STARTER) {
6
7
  return {
7
8
  path: "humanish/studies/local-browser.yaml",
8
9
  plane: "source",
@@ -34,19 +35,23 @@ defaults:
34
35
  };
35
36
  }
36
37
  /**
37
- * The flagship live lab. A ChatGPT-account Codex participant has no API-dollar price, so preflight
38
+ * The flagship live study. A ChatGPT-account Codex participant has no API-dollar price, so preflight
38
39
  * refuses a dollar cap on it (HUMANISH_COMPUTER_USE_UNPRICED_CAP); that variant is bounded by the
39
40
  * session timeout instead of a cap it could never enforce.
40
41
  */
41
- function tryLiveLab(actor, localAgent = "codex") {
42
+ function tryLiveStudy(actor, localAgent = "codex") {
42
43
  const account = actor === "local-agent";
43
44
  const needs = account
44
45
  ? ` Needs E2B_API_KEY and the coding agent signed in on this machine. Cost: one small task, a few
45
46
  E2B desktop minutes and the agent's account usage. humanish cannot put a dollar cap on account
46
- usage, so the ten-minute session limit below bounds the run.`
47
+ usage, so the ten-minute session limit below bounds the run. When OPENAI_API_KEY is set, the
48
+ analysis after the run bills it: humanish refuses that request before it starts if its estimate
49
+ is over $${DEFAULT_ANALYSIS_MAX_COST_USD}. Set review.analysis: false to skip it.`
47
50
  : ` Needs E2B_API_KEY and OPENAI_API_KEY. Cost: one small task with a $2 cap on estimated model
48
51
  spend. The run stops before its next model request once the estimate passes $2, so the last
49
- request can go slightly over, and hosted desktop time is billed separately.`;
52
+ request can go slightly over, and hosted desktop time is billed separately. The analysis after
53
+ the run bills the same key outside that cap: humanish refuses it before it starts if its
54
+ estimate is over $${DEFAULT_ANALYSIS_MAX_COST_USD}. Set review.analysis: false to skip it.`;
50
55
  const participant = account
51
56
  ? `# Your machine has a coding agent signed in, so this study uses it: no provider API key, only
52
57
  # E2B. To use a provider key instead, swap to \`type: openai-computer-use\` and add caps.maxUsd.
@@ -229,8 +234,8 @@ defaults:
229
234
  open: true
230
235
  `,
231
236
  },
232
- tryLiveLab("openai-computer-use"),
233
- localBrowserLab(),
237
+ tryLiveStudy("openai-computer-use"),
238
+ localBrowserStudy(),
234
239
  {
235
240
  path: "humanish/studies/cua-browser.yaml",
236
241
  plane: "source",
@@ -401,16 +406,16 @@ export const humanishScripts = {
401
406
  "humanish:verify": "humanish verify",
402
407
  };
403
408
  /**
404
- * The starter files, with the live lab written for the brain this machine can use.
409
+ * The starter files, with the live study written for the brain this machine can use.
405
410
  *
406
- * `local-agent` is not a variant of the lab so much as a different participant: on a machine with
411
+ * `local-agent` is not a variant of the study so much as a different participant: on a machine with
407
412
  * a signed-in Codex and no provider key, the study runs with the operator's own agent and needs
408
413
  * only E2B. Writing the other one there would hand someone homework instead of a first run.
409
414
  */
410
415
  export function starterFilesFor(actor, localBrowser = DEFAULT_LOCAL_BROWSER_STARTER, localAgent) {
411
416
  return starterFiles.map((file) => file.path === "humanish/studies/local-browser.yaml"
412
- ? localBrowserLab(localBrowser)
417
+ ? localBrowserStudy(localBrowser)
413
418
  : file.path === "humanish/studies/try-live.yaml"
414
- ? tryLiveLab(actor, localAgent)
419
+ ? tryLiveStudy(actor, localAgent)
415
420
  : file);
416
421
  }
@@ -5,7 +5,7 @@ export interface InitOptions {
5
5
  yes?: boolean;
6
6
  /** Injected so a test can decide what credentials this machine appears to have. */
7
7
  env?: NodeJS.ProcessEnv;
8
- /** Configure the starter local-browser lab without making the operator edit YAML. */
8
+ /** Configure the starter local-browser study without making the operator edit YAML. */
9
9
  localBrowser?: {
10
10
  appUrl: string;
11
11
  mission?: string;
@@ -8,7 +8,7 @@ import { assertPreparedSelectedOutputDirectory, prepareContainedOutputDirectory,
8
8
  import { validateCwd } from "../run/project.js";
9
9
  import { pathExists, readTextIfExists, validateInitProjectPaths } from "./init-paths.js";
10
10
  import { planGitignore, planPackageJson } from "./init-plan.js";
11
- import { otherStudyFiles, STUDY_DIRECTORIES, studyFileStem } from "../study/files.js";
11
+ import { otherStudyFiles, STUDY_DIRECTORIES, studyFileStem } from "./files.js";
12
12
  const INIT_RESPONSE_SCHEMA = "humanish.init-result.v1";
13
13
  export async function runInit(options) {
14
14
  const requestedCwd = path.resolve(options.cwd);
@@ -38,7 +38,7 @@ export async function runInit(options) {
38
38
  return failed(initialPathCheck);
39
39
  }
40
40
  await planAgentsFile(preparedProjectRoot, cwd, plan);
41
- // The starter live lab is written for the brain this machine can actually use. Shipping it as
41
+ // The starter live study is written for the brain this machine can actually use. Shipping it as
42
42
  // openai-computer-use on a machine with no provider key but a signed-in Codex would hand someone
43
43
  // a file that asks for a credential they were just told they do not need.
44
44
  const machine = await firstRunEnvironment(options.env ?? process.env, requestedCwd);
@@ -149,8 +149,11 @@ async function planStarterFiles(preparedProjectRoot, cwd, files, localBrowserReq
149
149
  target: file.plane,
150
150
  reason: `${others.join(", ")} already uses the name ${stem}`,
151
151
  });
152
+ // humanish no longer reads a labs/ file, but migrate needs its name free to move it.
152
153
  const legacy = others.some((other) => other.split(path.sep).includes("labs"));
153
- plan.warnings.push(`Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}, and a second file with that name would make \`run ${stem}\` fail.${legacy ? " Run humanish migrate to move it to a studies/ directory." : ""}`);
154
+ plan.warnings.push(legacy
155
+ ? `Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}. Move it to a studies/ directory; humanish migrate converts and moves a v2 file.`
156
+ : `Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}, and a second file with that name would make \`run ${stem}\` fail.`);
154
157
  }
155
158
  else if (existing === null) {
156
159
  plan.changes.push({
@@ -268,7 +271,7 @@ function validateLocalBrowserStarter(input) {
268
271
  return { ok: true, value };
269
272
  }
270
273
  /**
271
- * What this machine can run, for the starter lab and the next steps. Local CLI status is
274
+ * What this machine can run, for the starter study and the next steps. Local CLI status is
272
275
  * classified without returning its output or reading its credential file. Provider keys go
273
276
  * through the same discovery chain as every other command (process env, the project overlay,
274
277
  * `e2b auth login`, the `humanish keys set` store) and only their presence is read, never a value.
@@ -1,4 +1,4 @@
1
- /** The first key in `raw` that LAB_KEYS does not list, as an error message; undefined if none. */
2
- export declare function findUnknownLabKey(raw: unknown): string | undefined;
1
+ /** The first key in `raw` that V2_KEYS does not list, as an error message; undefined if none. */
2
+ export declare function findUnknownV2Key(raw: unknown): string | undefined;
3
3
  /** The first key in a humanish.study.v3 document that the format does not have; undefined if none. */
4
4
  export declare function findUnknownStudyKey(raw: unknown): string | undefined;
@@ -1,4 +1,4 @@
1
- // Every mapping key parseLabConfig reads, by path. A key that is not listed fails the lab as
1
+ // Every mapping key parseStudy reads, by path. A key that is not listed fails the study as
2
2
  // unknown, so a typo stops the run instead of being dropped. `true` marks a leaf: its parser
3
3
  // checks the value (scalars, lists, and mappings that check their own keys). Each level satisfies
4
4
  // the parsed type's keys, so a field added to a Lab* interface must be added here too.
@@ -166,7 +166,7 @@ const EMAIL = {
166
166
  allowedOrigins: true,
167
167
  recipients: { lane: true, address: true },
168
168
  };
169
- const LAB_KEYS = {
169
+ const V2_KEYS = {
170
170
  schema: true,
171
171
  id: true,
172
172
  title: true,
@@ -225,14 +225,14 @@ const STUDY_KEYS = {
225
225
  caps: CAPS,
226
226
  execution: without(EXECUTION, "caps"),
227
227
  scenario: true,
228
- policies: LAB_KEYS.policies,
229
- review: LAB_KEYS.review,
230
- defaults: LAB_KEYS.defaults,
231
- comms: LAB_KEYS.comms,
228
+ policies: V2_KEYS.policies,
229
+ review: V2_KEYS.review,
230
+ defaults: V2_KEYS.defaults,
231
+ comms: V2_KEYS.comms,
232
232
  };
233
- /** The first key in `raw` that LAB_KEYS does not list, as an error message; undefined if none. */
234
- export function findUnknownLabKey(raw) {
235
- return walk(raw, LAB_KEYS, "", "lab");
233
+ /** The first key in `raw` that V2_KEYS does not list, as an error message; undefined if none. */
234
+ export function findUnknownV2Key(raw) {
235
+ return walk(raw, V2_KEYS, "", "study");
236
236
  }
237
237
  /** The first key in a humanish.study.v3 document that the format does not have; undefined if none. */
238
238
  export function findUnknownStudyKey(raw) {
@@ -270,7 +270,7 @@ function unknownKeysMessage(path, unknown, known, noun) {
270
270
  const suggestion = closest(key, known);
271
271
  return suggestion ? `${key} (did you mean \`${suggestion}\`?)` : key;
272
272
  });
273
- return `Unknown ${noun} field(s)${path ? ` in \`${path}\`` : ""}: ${named.join(", ")}. Known fields: ${known.join(", ")}.`;
273
+ return `Unknown ${noun} ${unknown.length === 1 ? "field" : "fields"}${path ? ` in \`${path}\`` : ""}: ${named.join(", ")}. Known fields: ${known.join(", ")}.`;
274
274
  }
275
275
  // The known key within edit distance 2, or one that differs only in case.
276
276
  function closest(key, known) {
@@ -1,4 +1,4 @@
1
- import type { StudyRoute } from "../lab/parse/study-v3.js";
1
+ import type { StudyRoute } from "./routing.js";
2
2
  import { type DroppedKey, type MovedKey } from "./convert.js";
3
3
  /** The schema of `humanish migrate --json`. */
4
4
  declare const MIGRATE_SCHEMA = "humanish.migrate-result.v1";
@@ -1,14 +1,14 @@
1
- import type { LabActor, LabParticipantEntry, LabParticipantFocus, LabConfigParseFailure } from "../types.js";
1
+ import type { StudyActor, StudyParticipantEntry, StudyParticipantFocus, StudyParseFailure } from "../types.js";
2
2
  export declare const PARTICIPANT_ID_PATTERN: RegExp;
3
3
  export declare const PARTICIPANT_ID_MAX_CHARS = 40;
4
4
  /** The participant entries an actor declares, after roster groups expand into them. The manifest
5
5
  * spells them `actors[].lanes`. Undefined when the actor declares none. */
6
- export declare function rosterOf<Entry = LabParticipantEntry>(actor: {
6
+ export declare function rosterOf<Entry = StudyParticipantEntry>(actor: {
7
7
  readonly lanes?: readonly Entry[];
8
8
  } | undefined): readonly Entry[] | undefined;
9
9
  /** An actor's per-participant focus on the app-url route. The manifest spells it `laneFocus`. */
10
- export declare function focusOf(actor: Pick<LabActor, "laneFocus"> | undefined): LabParticipantFocus | undefined;
10
+ export declare function focusOf(actor: Pick<StudyActor, "laneFocus"> | undefined): StudyParticipantFocus | undefined;
11
11
  export declare function parseActors(raw: unknown): {
12
12
  ok: true;
13
- value: LabActor[];
14
- } | LabConfigParseFailure;
13
+ value: StudyActor[];
14
+ } | StudyParseFailure;
@@ -6,7 +6,7 @@ import { registeredComputerUseActors, registeredScriptedBrowserActors, registere
6
6
  import { invalid, posInt, str } from "./values.js";
7
7
  import { isRecord } from "../../run/type-guards.js";
8
8
  // A participant id interpolates into its evidence paths (screenshots/<id>/, actors/<id>.json), so
9
- // it must be a public-safe path token, same shape as a lab id.
9
+ // it must be a public-safe path token, same shape as a study id.
10
10
  export const PARTICIPANT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
11
11
  export const PARTICIPANT_ID_MAX_CHARS = 40;
12
12
  const METADATA_MAX_CHARS = 80;
@@ -19,7 +19,7 @@ export function rosterOf(actor) {
19
19
  export function focusOf(actor) {
20
20
  return actor?.laneFocus;
21
21
  }
22
- // Actor ids humanish no longer registers. Rejecting them at parse keeps a lab that names one
22
+ // Actor ids humanish no longer registers. Rejecting them at parse keeps a study that names one
23
23
  // from running on a route that ignores actors[0].type, such as a this-repo dry run.
24
24
  const REMOVED_ACTOR_TYPES = new Set(["pi-agent-core", "claude-agent-sdk"]);
25
25
  // Only actors of a run kind a route dispatches. codex-app-server is registered but declares only
@@ -33,7 +33,7 @@ function routableActorTypes() {
33
33
  }
34
34
  export function parseActors(raw) {
35
35
  if (!Array.isArray(raw) || raw.length === 0) {
36
- return invalid("Lab `actors` must be a non-empty array.");
36
+ return invalid("`actors` must be a non-empty array.");
37
37
  }
38
38
  // Multi-actor fan-out is not wired yet (only actors[0] is consumed). Fail closed rather than
39
39
  // silently ignore actors[1..]; multi-actor support lands in a later slice.
@@ -50,7 +50,7 @@ export function parseActors(raw) {
50
50
  return invalid(`actors[${index}].type is required.`);
51
51
  }
52
52
  if (REMOVED_ACTOR_TYPES.has(type)) {
53
- return invalid(`actors[${index}].type "${type}" is no longer a humanish actor. Use an actor a lab route runs (one of: ${routableActorTypes().join(", ")}). To drive a study with a signed-in Claude Code, use type: local-agent with localAgent: claude.`);
53
+ return invalid(`actors[${index}].type "${type}" is no longer a humanish actor. Use an actor a study route runs (one of: ${routableActorTypes().join(", ")}). To drive a study with a signed-in Claude Code, use type: local-agent with localAgent: claude.`);
54
54
  }
55
55
  const actor = { type };
56
56
  const count = posInt(entry.count);
@@ -189,7 +189,7 @@ function parseRosterGroups(raw, actorIndex) {
189
189
  * Participant ids (when declared) must be public-safe path tokens and unique; grouping metadata
190
190
  * must be public-safe tokens; a device must be a known preset name. The
191
191
  * route-scoped cross-validation (`lanes` XOR `count`/`laneFocus`, device XOR raw resolution, cap 16)
192
- * runs in parseLabConfig where the route is known.
192
+ * runs in parseStudy where the route is known.
193
193
  */
194
194
  function parseParticipantEntries(raw, actorIndex) {
195
195
  if (raw === undefined) {
@@ -0,0 +1,12 @@
1
+ import type { StudyComms, StudyCommsEmail, StudyCommsRecipient, StudyParseFailure } from "../types.js";
2
+ export declare function parseComms(raw: unknown): {
3
+ ok: true;
4
+ value: StudyComms | undefined;
5
+ } | StudyParseFailure;
6
+ /** The participant a declared inbox recipient belongs to. The manifest spells it `lane`. */
7
+ export declare function recipientParticipantId(recipient: StudyCommsRecipient): string;
8
+ /** The declared recipients that name an address, in declaration order, by participant id. */
9
+ export declare function addressedRecipients(email: Pick<StudyCommsEmail, "recipients">): {
10
+ participantId: string;
11
+ address: string;
12
+ }[];
@@ -0,0 +1,19 @@
1
+ import type { StudyParseFailure, StudyDefaults, StudyExecution, StudyPolicies, StudyReview, StudyScenario } from "../types.js";
2
+ export declare function parseExecution(raw: unknown): {
3
+ ok: true;
4
+ value: StudyExecution | undefined;
5
+ } | StudyParseFailure;
6
+ export declare function parsePersonas(raw: unknown): Record<string, unknown>[] | undefined;
7
+ export declare function parseScenario(raw: unknown): {
8
+ ok: true;
9
+ value: StudyScenario | undefined;
10
+ } | StudyParseFailure;
11
+ export declare function parsePolicies(raw: unknown): {
12
+ ok: true;
13
+ value: StudyPolicies | undefined;
14
+ } | StudyParseFailure;
15
+ export declare function parseReview(raw: unknown): {
16
+ ok: true;
17
+ value: StudyReview | undefined;
18
+ } | StudyParseFailure;
19
+ export declare function parseDefaults(raw: unknown): StudyDefaults | undefined;
@@ -1,7 +1,5 @@
1
- import { type LabConfigParseFailure } from "../types.js";
2
- declare const ROUTES: readonly ["preview", "computer-use", "shared-world", "terminal", "scripted"];
3
- /** A route a study declares. */
4
- export type StudyRoute = (typeof ROUTES)[number];
1
+ import type { StudyRoute } from "../routing.js";
2
+ import { type StudyParseFailure } from "../types.js";
5
3
  export interface StudyDocument {
6
4
  readonly route: StudyRoute;
7
5
  /** The same document in the humanish.lab.v2 spelling. */
@@ -12,7 +10,7 @@ export interface StudyDocument {
12
10
  type Parsed<T> = {
13
11
  ok: true;
14
12
  value: T;
15
- } | LabConfigParseFailure;
13
+ } | StudyParseFailure;
16
14
  /** Rewrite a humanish.study.v3 document into humanish.lab.v2, or refuse it. */
17
15
  export declare function studyToV2(raw: Record<string, unknown>): Parsed<StudyDocument>;
18
16
  /**
@@ -1,10 +1,10 @@
1
1
  // humanish.study.v3, the study format. A study declares its route, one `actor`, its `participants`
2
2
  // and one `caps` block. studyToV2 rewrites a v3 document into the v2 spelling, so both formats run
3
- // through one parser and parse into the same LabConfig. parseLabConfig then checks the declared
3
+ // through one parser and parse into the same StudyConfig. parseStudy then checks the declared
4
4
  // route against the one the config takes, and refuses any field that route does not read.
5
5
  import { isRecord } from "../../run/type-guards.js";
6
6
  import { findUnknownStudyKey } from "../keys.js";
7
- import { LAB_CONFIG_SCHEMA } from "../types.js";
7
+ import { V2_SCHEMA } from "../types.js";
8
8
  import { PARTICIPANT_ID_MAX_CHARS, PARTICIPANT_ID_PATTERN } from "./actors.js";
9
9
  import { invalid, posInt } from "./values.js";
10
10
  // The values `route:` takes: every route routeOf can return.
@@ -81,7 +81,7 @@ export function studyToV2(raw) {
81
81
  ? withKey(raw.execution, "caps", caps)
82
82
  : raw.execution;
83
83
  const subject = route === "shared-world" ? withKey(raw.subject, "topology", "shared-world") : raw.subject;
84
- const v2 = { schema: LAB_CONFIG_SCHEMA };
84
+ const v2 = { schema: V2_SCHEMA };
85
85
  const fields = [
86
86
  ["id", raw.id],
87
87
  ["title", raw.title],
@@ -1,4 +1,4 @@
1
- import type { LabConfigParseFailure, LabSubjectState } from "../types.js";
1
+ import type { StudyParseFailure, StudySubjectState } from "../types.js";
2
2
  /**
3
3
  * Literal non-secret subject env. Real apps need configuration before they will boot: a public base
4
4
  * URL, a transport selector, a feature flag, and none of that is secret. Routing it through
@@ -10,21 +10,21 @@ import type { LabConfigParseFailure, LabSubjectState } from "../types.js";
10
10
  export declare function parseEnvValues(raw: unknown): {
11
11
  ok: true;
12
12
  value?: Record<string, string>;
13
- } | LabConfigParseFailure;
13
+ } | StudyParseFailure;
14
14
  /**
15
- * Structural parse of `subject.state` into a candidate LabSubjectState. Deliberately keeps
15
+ * Structural parse of `subject.state` into a candidate StudySubjectState. Deliberately keeps
16
16
  * unrecognized `when`/`timeoutMs` values in the candidate (instead of silently dropping
17
17
  * them) so subjectStateInvalidReason rejects them: a state declaration that silently does
18
18
  * less than it says would claim more than its mechanism does.
19
19
  */
20
20
  export declare function parseState(raw: unknown): {
21
21
  ok: true;
22
- value: LabSubjectState | undefined;
23
- } | LabConfigParseFailure;
22
+ value: StudySubjectState | undefined;
23
+ } | StudyParseFailure;
24
24
  /**
25
- * Semantic validation for `subject.state`, shared by parseLabConfig and the engine
26
- * (the route re-enforces it on configs that arrive through runLab). Returns
25
+ * Semantic validation for `subject.state`, shared by parseStudy and the engine
26
+ * (the route re-enforces it on configs that arrive through runStudyWith). Returns
27
27
  * the failure message, or null when the declaration is valid. Reads the candidate
28
28
  * defensively: library callers can hand the engine arbitrarily-shaped objects.
29
29
  */
30
- export declare function subjectStateInvalidReason(state: LabSubjectState, env: readonly string[] | undefined): string | null;
30
+ export declare function subjectStateInvalidReason(state: StudySubjectState, env: readonly string[] | undefined): string | null;
@@ -1,6 +1,6 @@
1
1
  // The state and env channels of a served subject (clone or local-tree): `subject.envValues`,
2
2
  // the structural parse of `subject.state`, and subjectStateInvalidReason, the semantic check
3
- // parseLabConfig and the computer-use route share.
3
+ // parseStudy and the computer-use route share.
4
4
  import { containsSensitive } from "../../evidence/redaction.js";
5
5
  import { ENV_NAME_PATTERN, invalid, posInt, str, strList } from "./values.js";
6
6
  import { isRecord } from "../../run/type-guards.js";
@@ -39,7 +39,7 @@ export function parseEnvValues(raw) {
39
39
  return { ok: true, value: envValues };
40
40
  }
41
41
  /**
42
- * Structural parse of `subject.state` into a candidate LabSubjectState. Deliberately keeps
42
+ * Structural parse of `subject.state` into a candidate StudySubjectState. Deliberately keeps
43
43
  * unrecognized `when`/`timeoutMs` values in the candidate (instead of silently dropping
44
44
  * them) so subjectStateInvalidReason rejects them: a state declaration that silently does
45
45
  * less than it says would claim more than its mechanism does.
@@ -96,8 +96,8 @@ const STATE_STEP_WHENS = [
96
96
  "after-ready",
97
97
  ];
98
98
  /**
99
- * Semantic validation for `subject.state`, shared by parseLabConfig and the engine
100
- * (the route re-enforces it on configs that arrive through runLab). Returns
99
+ * Semantic validation for `subject.state`, shared by parseStudy and the engine
100
+ * (the route re-enforces it on configs that arrive through runStudyWith). Returns
101
101
  * the failure message, or null when the declaration is valid. Reads the candidate
102
102
  * defensively: library callers can hand the engine arbitrarily-shaped objects.
103
103
  */
@@ -1,8 +1,8 @@
1
- import type { LabConfigParseFailure, LabSubject } from "../types.js";
1
+ import type { StudyParseFailure, StudySubject } from "../types.js";
2
2
  export declare function parseSubject(raw: unknown): {
3
3
  ok: true;
4
- value: LabSubject;
5
- } | LabConfigParseFailure;
4
+ value: StudySubject;
5
+ } | StudyParseFailure;
6
6
  export declare const PUBLIC_TARGET_OWNER_PATTERN: RegExp;
7
7
  export declare function isLoopbackUrl(value: string): boolean;
8
8
  /** A well-formed http(s) URL (any host). Shape gate before the loopback/public-target policy. */
@@ -4,7 +4,7 @@ import { parseEnvValues, parseState, subjectStateInvalidReason } from "./subject
4
4
  import { isRecord } from "../../run/type-guards.js";
5
5
  export function parseSubject(raw) {
6
6
  if (!isRecord(raw)) {
7
- return invalid("Lab `subject` is required and must be an object.");
7
+ return invalid("`subject` is required and must be an object.");
8
8
  }
9
9
  const source = str(raw.source);
10
10
  if (source !== "this-repo" &&
@@ -71,19 +71,19 @@ function misplacedFieldFailure(source, raw) {
71
71
  // tree): both routes serve a subject in-sandbox with the same install/build/start/url +
72
72
  // env-name + seed/external/checkpoint shapes.
73
73
  if (source !== "clone" && source !== "local-tree" && raw.serve !== undefined) {
74
- return invalid("`subject.serve` applies only to clone subjects or local-tree subjects (the lab serves the cloned/packed app in-sandbox).");
74
+ return invalid("`subject.serve` applies only to clone subjects or local-tree subjects (humanish serves the cloned or packed app in the sandbox).");
75
75
  }
76
76
  if (source !== "clone" && source !== "local-tree" && raw.env !== undefined) {
77
77
  return invalid("`subject.env` applies only to clone subjects or local-tree subjects (the served app's environment channel).");
78
78
  }
79
79
  if (source !== "clone" && source !== "local-tree" && raw.state !== undefined) {
80
- return invalid("`subject.state` applies only to clone subjects or local-tree subjects (the lab seeds the state it serves).");
80
+ return invalid("`subject.state` applies only to clone subjects or local-tree subjects (humanish seeds the state it serves).");
81
81
  }
82
82
  // repos/clone are clone-only (a fresh-clone subject's git inputs). local-tree packs the
83
83
  // resolution cwd itself, so it has no repo slug to clone and gets its own precise reasons
84
84
  // rather than falling through to the generic clone-only message below.
85
85
  if (source === "local-tree" && raw.repos !== undefined) {
86
- return invalid("`subject.repos` does not apply to local-tree subjects. The local-tree route packs the lab resolution cwd itself; there is no owner/repo slug to clone.");
86
+ return invalid("`subject.repos` does not apply to local-tree subjects. The local-tree route packs the study's working directory itself; there is no owner/repo slug to clone.");
87
87
  }
88
88
  if (source === "local-tree" && raw.clone !== undefined) {
89
89
  return invalid("`subject.clone` does not apply to local-tree subjects. Declare `subject.localTree` instead (keep/exclude/maxArchiveBytes).");
@@ -126,7 +126,7 @@ function parseCloneSubject(raw, subject) {
126
126
  function parseLocalTreeSubject(raw, subject) {
127
127
  // A local-tree subject exists to be packed and served; there is no other way to boot it, so
128
128
  // serve is required here. Clone subjects get the same requirement from each route's checks in
129
- // parseLabConfig.
129
+ // parseStudy.
130
130
  if (raw.serve === undefined) {
131
131
  return invalid("`subject.serve` is required when source is local-tree: a local-tree subject exists to be packed and served, so declare install/build/start/url exactly like the clone route.");
132
132
  }
@@ -175,7 +175,7 @@ function parseServedApp(raw, subject) {
175
175
  return stateResult;
176
176
  }
177
177
  if (stateResult.value) {
178
- // Semantic validation is shared with the engine (runCuaActorLab re-enforces it for
178
+ // Semantic validation is shared with the engine (runCuaActorStudy re-enforces it for
179
179
  // configs that arrive through the library API without the parser).
180
180
  const reason = subjectStateInvalidReason(stateResult.value, subject.env);
181
181
  if (reason) {
@@ -241,7 +241,7 @@ function parsePublicTarget(raw) {
241
241
  return { ok: true, value: { owner, authorized: true } };
242
242
  }
243
243
  // The product name interpolates into evidence labels and the composed prompt; the public-safe
244
- // token shape is the same strict constraint as a lab id.
244
+ // token shape is the same strict constraint as a study id.
245
245
  const PRODUCT_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
246
246
  function parseProduct(raw) {
247
247
  if (!isRecord(raw)) {
@@ -289,7 +289,7 @@ function parseProduct(raw) {
289
289
  },
290
290
  };
291
291
  }
292
- // Public-safe stance: a computer-use actor's entry URL is always an app the lab owner runs on
292
+ // Public-safe stance: a computer-use actor's entry URL is always an app the study owner runs on
293
293
  // loopback (inside the sandbox), never an arbitrary public site. (The constraint binds the
294
294
  // entry point; a navigation watchdog for mid-session escapes is a later slice.) Exported so
295
295
  // the engine re-enforces the same boundary on configs that arrive through the library API.
@@ -1,7 +1,7 @@
1
- import type { LabConfigParseFailure } from "../types.js";
1
+ import type { StudyParseFailure } from "../types.js";
2
2
  export declare const REPO_SLUG_PATTERN: RegExp;
3
3
  export declare const ENV_NAME_PATTERN: RegExp;
4
- export declare function invalid(message: string): LabConfigParseFailure;
4
+ export declare function invalid(message: string): StudyParseFailure;
5
5
  export declare function str(value: unknown): string | undefined;
6
6
  export declare function optionalStr(key: string, value: unknown): Record<string, string>;
7
7
  export declare function strList(value: unknown): string[] | undefined;
@@ -1,6 +1,6 @@
1
1
  import { type ResolvedPersona } from "./persona.js";
2
2
  import { type PreparedSelectedOutputDirectory } from "../run/contained-output.js";
3
- import type { LabActor } from "./types.js";
3
+ import type { StudyActor } from "./types.js";
4
4
  /** Title-case an id for the fallback display name (`skeptical-power-user` -> `Skeptical Power User`). */
5
5
  export declare function personaTitleFromId(personaId: string): string;
6
6
  /**
@@ -22,11 +22,11 @@ export declare function resolveCommittedPersonas(projectRoot: PreparedSelectedOu
22
22
  warnings: string[];
23
23
  }>;
24
24
  /**
25
- * Every persona id a lab config could put on a browser participant: the roster when one is
25
+ * Every persona id a study config could put on a browser participant: the roster when one is
26
26
  * declared, otherwise the actor-level persona that every fan-out participant inherits.
27
27
  */
28
- export declare function labPersonaIds(config: {
29
- actors?: readonly Pick<LabActor, "persona" | "lanes">[];
28
+ export declare function studyPersonaIds(config: {
29
+ actors?: readonly Pick<StudyActor, "persona" | "lanes">[];
30
30
  }): string[];
31
31
  /**
32
32
  * Same resolution from a plain cwd, for the labs that carry a directory string rather than an
@@ -81,10 +81,10 @@ export async function resolveCommittedPersonas(projectRoot, personaIds) {
81
81
  return { personas, warnings };
82
82
  }
83
83
  /**
84
- * Every persona id a lab config could put on a browser participant: the roster when one is
84
+ * Every persona id a study config could put on a browser participant: the roster when one is
85
85
  * declared, otherwise the actor-level persona that every fan-out participant inherits.
86
86
  */
87
- export function labPersonaIds(config) {
87
+ export function studyPersonaIds(config) {
88
88
  const ids = [];
89
89
  for (const actor of config.actors ?? []) {
90
90
  if (actor.persona)
@@ -1,25 +1,25 @@
1
1
  import type { Brain, ComputerUsePlan, NonEmpty, PlannedAnalysis, ProvisionedSubject, Requirement } from "./plan-types.js";
2
- import type { LabConfig } from "./types.js";
2
+ import type { StudyConfig } from "./types.js";
3
3
  export type Base = Omit<ComputerUsePlan, "route" | "actor" | "runner" | "concurrency" | "sessionBudgetMs" | "sandboxMs" | "caps" | "rerun">;
4
4
  export declare function isNonEmpty<T>(values: readonly T[]): values is NonEmpty<T>;
5
- export declare function capsOf(config: LabConfig): ComputerUsePlan["caps"];
6
- export declare function provisionedSubject(config: LabConfig): ProvisionedSubject | undefined;
5
+ export declare function capsOf(config: StudyConfig): ComputerUsePlan["caps"];
6
+ export declare function provisionedSubject(config: StudyConfig): ProvisionedSubject | undefined;
7
7
  /** Keys, env and local tools a live run checks right before it acquires anything. */
8
- export declare function desktopRequirements(config: LabConfig, args: {
8
+ export declare function desktopRequirements(config: StudyConfig, args: {
9
9
  e2b: boolean;
10
10
  brain: Brain;
11
11
  localVm: boolean;
12
12
  externalCatch: boolean;
13
13
  }): Requirement[];
14
- export declare function brainOf(config: LabConfig, callerProvider: boolean): Brain;
14
+ export declare function brainOf(config: StudyConfig, callerProvider: boolean): Brain;
15
15
  /** The brain of a run whose provider the library caller supplies. */
16
- export declare function callerBrainOf(config: LabConfig): Extract<Brain, {
16
+ export declare function callerBrainOf(config: StudyConfig): Extract<Brain, {
17
17
  kind: "caller";
18
18
  }>;
19
19
  /** The model a participant's spend is priced at when its provider reports none. */
20
20
  export declare function pricedModel(brain: Brain): string;
21
21
  /** The fields every plan shares, from a config whose analysis already resolved. */
22
- export declare function planBase(config: LabConfig, input: {
22
+ export declare function planBase(config: StudyConfig, input: {
23
23
  readonly dryRun: boolean;
24
24
  readonly analysis?: {
25
25
  readonly config?: PlannedAnalysis["config"] | undefined;
@@ -110,7 +110,7 @@ export function pricedModel(brain) {
110
110
  export function planBase(config, input) {
111
111
  const analysis = input.analysis?.config;
112
112
  return {
113
- labId: config.id,
113
+ studyId: config.id,
114
114
  ...(config.title === undefined ? {} : { title: config.title }),
115
115
  residual: residualOf(config),
116
116
  dryRun: input.dryRun,
@@ -1,8 +1,8 @@
1
1
  import type { DwellWindow, StopWhen } from "../actors/stop-conditions.js";
2
2
  import type { ReasoningEffort } from "../actors/reasoning-effort.js";
3
3
  import { type DevicePreset } from "./device-presets.js";
4
- import type { LabTask } from "./tasks.js";
5
- import type { LabConfig } from "./types.js";
4
+ import type { StudyTask } from "./tasks.js";
5
+ import type { StudyConfig } from "./types.js";
6
6
  /** Who one participant is. Every route with participants carries this record. */
7
7
  export interface Participant {
8
8
  /** Declared roster id, else `lane-NN` (independent participants) or `role-NN` (shared-world participants). */
@@ -40,7 +40,7 @@ interface DesktopParticipant extends Participant {
40
40
  }
41
41
  /** Only independent computer-use participants consume a task protocol and their own target. */
42
42
  export interface ComputerUseParticipant extends DesktopParticipant {
43
- readonly tasks?: readonly LabTask[];
43
+ readonly tasks?: readonly StudyTask[];
44
44
  /** app-url fan-out only: this participant's own entry URL; absent means the subject URL. */
45
45
  readonly targetUrl?: string;
46
46
  }
@@ -68,14 +68,14 @@ export type SharedWorldRoster = {
68
68
  /** One shared-world participant on either plane. */
69
69
  export type SharedWorldParticipant = ProvisionedParticipant | ExternalPublicParticipant;
70
70
  /**
71
- * The participants of a computer-use lab: the declared roster, else `count` identical ones. A count
71
+ * The participants of a computer-use study: the declared roster, else `count` identical ones. A count
72
72
  * override (`--count`) applies only when no roster is declared.
73
73
  */
74
- export declare function computerUseParticipants(config: LabConfig, countOverride?: number): ComputerUseParticipant[];
75
- /** The participants of a shared-world lab, one per roster entry, typed by the plane they share. */
76
- export declare function sharedWorldParticipants(config: LabConfig): SharedWorldRoster;
77
- /** The ids of the participants a computer-use or shared-world lab runs, in roster order. */
78
- export declare function declaredParticipantIds(config: LabConfig): string[];
74
+ export declare function computerUseParticipants(config: StudyConfig, countOverride?: number): ComputerUseParticipant[];
75
+ /** The participants of a shared-world study, one per roster entry, typed by the plane they share. */
76
+ export declare function sharedWorldParticipants(config: StudyConfig): SharedWorldRoster;
77
+ /** The ids of the participants a computer-use or shared-world study runs, in roster order. */
78
+ export declare function declaredParticipantIds(config: StudyConfig): string[];
79
79
  /** The entry URLs roster entries declare in place of the subject URL (computer use, app-url). */
80
- export declare function declaredTargets(config: LabConfig): string[];
80
+ export declare function declaredTargets(config: StudyConfig): string[];
81
81
  export {};