humanish 0.108.0 → 0.109.1

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 (461) hide show
  1. package/ARCHITECTURE.md +58 -59
  2. package/CHANGELOG.md +22 -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/migrate.js +15 -4
  57. package/dist/cli/commands/observe.d.ts +0 -1
  58. package/dist/cli/commands/observe.js +0 -15
  59. package/dist/cli/commands/run-command.d.ts +2 -2
  60. package/dist/cli/commands/run-command.js +3 -3
  61. package/dist/cli/commands/runs.js +9 -7
  62. package/dist/cli/commands/setup.js +5 -7
  63. package/dist/cli/commands/study-format.d.ts +9 -0
  64. package/dist/cli/commands/{lab-format.js → study-format.js} +5 -5
  65. package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
  66. package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +12 -12
  67. package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
  68. package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
  69. package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
  70. package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +3 -3
  71. package/dist/cli/commands/study-route-run.d.ts +19 -0
  72. package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
  73. package/dist/cli/commands/study-route-scripted.d.ts +17 -0
  74. package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
  75. package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
  76. package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +7 -7
  77. package/dist/cli/commands/study-route-terminal.d.ts +17 -0
  78. package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
  79. package/dist/cli/commands/study-run.d.ts +9 -0
  80. package/dist/cli/commands/{lab-run.js → study-run.js} +34 -34
  81. package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +5 -5
  82. package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +1 -1
  83. package/dist/cli/commands/study.js +13 -49
  84. package/dist/cli/commands/tui.js +12 -12
  85. package/dist/cli/commands/watch.js +30 -65
  86. package/dist/cli/deprecations.d.ts +1 -13
  87. package/dist/cli/deprecations.js +0 -30
  88. package/dist/cli/doctor.d.ts +3 -3
  89. package/dist/cli/doctor.js +16 -16
  90. package/dist/cli/first-run-path.d.ts +4 -4
  91. package/dist/cli/first-run-path.js +7 -7
  92. package/dist/cli/io.d.ts +3 -3
  93. package/dist/cli/io.js +2 -2
  94. package/dist/cli/observer-follow.d.ts +2 -2
  95. package/dist/cli/observer-follow.js +2 -2
  96. package/dist/cli/orientation.d.ts +4 -4
  97. package/dist/cli/orientation.js +58 -20
  98. package/dist/cli/program.js +3 -4
  99. package/dist/cli/telemetry.d.ts +1 -1
  100. package/dist/cli/telemetry.js +14 -20
  101. package/dist/comms/catch-host.d.ts +1 -1
  102. package/dist/comms/catch-host.js +3 -3
  103. package/dist/comms/connections.d.ts +1 -1
  104. package/dist/comms/connections.js +2 -2
  105. package/dist/comms/external-evidence.d.ts +5 -5
  106. package/dist/comms/external-evidence.js +4 -3
  107. package/dist/comms/fake-inbox.d.ts +2 -2
  108. package/dist/comms/fake-inbox.js +2 -2
  109. package/dist/comms/receiving-runtime.d.ts +4 -4
  110. package/dist/comms/sandbox-catch.d.ts +2 -2
  111. package/dist/comms/sandbox-catch.js +2 -2
  112. package/dist/comms/setup.d.ts +2 -2
  113. package/dist/comms/setup.js +29 -32
  114. package/dist/evidence/redaction.d.ts +11 -0
  115. package/dist/evidence/redaction.js +43 -0
  116. package/dist/feedback/draft.js +2 -2
  117. package/dist/feedback/export-bundle.js +5 -4
  118. package/dist/feedback/export.js +3 -2
  119. package/dist/feedback/proof.d.ts +1 -1
  120. package/dist/feedback/proof.js +2 -2
  121. package/dist/guest/bootstrap.js +6 -6
  122. package/dist/guest/browser-tools.js +8 -8
  123. package/dist/guest/chromium-text.js +17 -17
  124. package/dist/guest/desktop-executor.d.ts +2 -2
  125. package/dist/guest/desktop-executor.js +20 -20
  126. package/dist/guest/desktop-keys.js +4 -4
  127. package/dist/guest/desktop-media.d.ts +2 -2
  128. package/dist/guest/desktop-media.js +16 -16
  129. package/dist/guest/desktop-native.js +10 -10
  130. package/dist/guest/runtime-desktop.js +2 -2
  131. package/dist/guest/runtime-processes.d.ts +2 -2
  132. package/dist/guest/runtime-processes.js +2 -2
  133. package/dist/guest/runtime.js +5 -5
  134. package/dist/index.d.ts +13 -15
  135. package/dist/index.js +6 -8
  136. package/dist/observer/artifact.d.ts +1 -1
  137. package/dist/observer/artifact.js +1 -1
  138. package/dist/observer/data.d.ts +1 -1
  139. package/dist/observer/library.d.ts +2 -0
  140. package/dist/observer/library.js +4 -1
  141. package/dist/observer/render.js +7 -1
  142. package/dist/observer/run-routes.d.ts +1 -0
  143. package/dist/observer/run-routes.js +37 -12
  144. package/dist/observer/serve.d.ts +1 -1
  145. package/dist/observer-app.html +1 -1
  146. package/dist/routes/computer-use/bundle-parts.js +3 -2
  147. package/dist/routes/computer-use/bundle.d.ts +2 -2
  148. package/dist/routes/computer-use/bundle.js +7 -6
  149. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +5 -5
  150. package/dist/routes/computer-use/e2b-desktop/comms.js +5 -4
  151. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +1 -1
  152. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
  153. package/dist/routes/computer-use/e2b-desktop/prepare.js +3 -3
  154. package/dist/routes/computer-use/e2b-desktop/start.js +3 -4
  155. package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
  156. package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -3
  157. package/dist/routes/computer-use/external-comms.d.ts +3 -3
  158. package/dist/routes/computer-use/fanout-bundle.js +11 -10
  159. package/dist/routes/computer-use/fanout-records.js +2 -2
  160. package/dist/routes/computer-use/in-process-desktop.js +1 -1
  161. package/dist/routes/computer-use/live-flush.d.ts +3 -3
  162. package/dist/routes/computer-use/live-phase.d.ts +2 -3
  163. package/dist/routes/computer-use/live-phase.js +3 -3
  164. package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
  165. package/dist/routes/computer-use/local-tree-pack.js +1 -1
  166. package/dist/routes/computer-use/local-vm.d.ts +8 -8
  167. package/dist/routes/computer-use/local-vm.js +2 -2
  168. package/dist/routes/computer-use/participant-desktop.d.ts +3 -3
  169. package/dist/routes/computer-use/participant-desktop.js +1 -1
  170. package/dist/routes/computer-use/participant-execution.js +1 -1
  171. package/dist/routes/computer-use/participant-model.js +3 -3
  172. package/dist/routes/computer-use/participant-prompt.d.ts +5 -5
  173. package/dist/routes/computer-use/participant-prompt.js +3 -3
  174. package/dist/routes/computer-use/participant-runs.d.ts +10 -10
  175. package/dist/routes/computer-use/participant-runs.js +14 -13
  176. package/dist/routes/computer-use/plan.d.ts +12 -12
  177. package/dist/routes/computer-use/plan.js +27 -27
  178. package/dist/routes/computer-use/preflight.d.ts +5 -5
  179. package/dist/routes/computer-use/preflight.js +5 -5
  180. package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
  181. package/dist/routes/computer-use/rerun-selection.js +3 -2
  182. package/dist/routes/computer-use/result.d.ts +4 -4
  183. package/dist/routes/computer-use/result.js +13 -12
  184. package/dist/routes/computer-use/route.d.ts +12 -12
  185. package/dist/routes/computer-use/route.js +19 -19
  186. package/dist/routes/computer-use/self-report.js +1 -1
  187. package/dist/routes/computer-use/setup.d.ts +22 -22
  188. package/dist/routes/computer-use/setup.js +15 -15
  189. package/dist/routes/computer-use/single-bundle.d.ts +4 -4
  190. package/dist/routes/computer-use/single-bundle.js +14 -13
  191. package/dist/routes/computer-use/subject-projection.d.ts +3 -3
  192. package/dist/routes/computer-use/types.d.ts +34 -34
  193. package/dist/routes/computer-use/types.js +3 -3
  194. package/dist/routes/preview.d.ts +6 -6
  195. package/dist/routes/preview.js +5 -5
  196. package/dist/routes/scripted/bundle.d.ts +6 -6
  197. package/dist/routes/scripted/bundle.js +10 -9
  198. package/dist/routes/scripted/plan.d.ts +7 -7
  199. package/dist/routes/scripted/plan.js +6 -6
  200. package/dist/routes/scripted/result.d.ts +3 -3
  201. package/dist/routes/scripted/result.js +9 -9
  202. package/dist/routes/scripted/route.d.ts +9 -9
  203. package/dist/routes/scripted/route.js +11 -11
  204. package/dist/routes/scripted/scenario.d.ts +1 -1
  205. package/dist/routes/scripted/scenario.js +3 -3
  206. package/dist/routes/scripted/setup.d.ts +6 -6
  207. package/dist/routes/scripted/setup.js +4 -4
  208. package/dist/routes/scripted/subject.d.ts +5 -5
  209. package/dist/routes/scripted/subject.js +3 -3
  210. package/dist/routes/scripted/surface-records.d.ts +1 -1
  211. package/dist/routes/scripted/surface-records.js +2 -2
  212. package/dist/routes/scripted/surface-sessions.d.ts +3 -3
  213. package/dist/routes/scripted/types.d.ts +17 -17
  214. package/dist/routes/scripted/types.js +1 -1
  215. package/dist/routes/shared-world/bundle-records.js +3 -3
  216. package/dist/routes/shared-world/bundle.js +15 -14
  217. package/dist/routes/shared-world/checkpoints.d.ts +3 -3
  218. package/dist/routes/shared-world/checkpoints.js +1 -1
  219. package/dist/routes/shared-world/comms.d.ts +9 -9
  220. package/dist/routes/shared-world/comms.js +6 -5
  221. package/dist/routes/shared-world/participant-specs.d.ts +3 -3
  222. package/dist/routes/shared-world/participant-specs.js +7 -7
  223. package/dist/routes/shared-world/plan.d.ts +9 -9
  224. package/dist/routes/shared-world/plan.js +9 -9
  225. package/dist/routes/shared-world/provisioned.d.ts +8 -8
  226. package/dist/routes/shared-world/provisioned.js +4 -4
  227. package/dist/routes/shared-world/result.d.ts +6 -6
  228. package/dist/routes/shared-world/result.js +11 -10
  229. package/dist/routes/shared-world/route.d.ts +11 -11
  230. package/dist/routes/shared-world/route.js +19 -19
  231. package/dist/routes/shared-world/setup.d.ts +13 -13
  232. package/dist/routes/shared-world/setup.js +19 -19
  233. package/dist/routes/shared-world/types.d.ts +27 -27
  234. package/dist/routes/terminal/adapter.d.ts +2 -2
  235. package/dist/routes/terminal/adapter.js +4 -4
  236. package/dist/routes/terminal/bundle.d.ts +11 -11
  237. package/dist/routes/terminal/bundle.js +12 -12
  238. package/dist/routes/terminal/credentials.d.ts +4 -4
  239. package/dist/routes/terminal/credentials.js +5 -5
  240. package/dist/routes/terminal/dry-run.d.ts +4 -4
  241. package/dist/routes/terminal/dry-run.js +9 -9
  242. package/dist/routes/terminal/ledger.d.ts +2 -2
  243. package/dist/routes/terminal/lifetime.d.ts +1 -1
  244. package/dist/routes/terminal/lifetime.js +1 -1
  245. package/dist/routes/terminal/live-finish.d.ts +2 -2
  246. package/dist/routes/terminal/live-finish.js +7 -7
  247. package/dist/routes/terminal/live-sandbox.d.ts +2 -2
  248. package/dist/routes/terminal/live-sandbox.js +3 -2
  249. package/dist/routes/terminal/participant-text.js +2 -1
  250. package/dist/routes/terminal/persona.d.ts +2 -2
  251. package/dist/routes/terminal/persona.js +2 -2
  252. package/dist/routes/terminal/plan.d.ts +7 -7
  253. package/dist/routes/terminal/plan.js +5 -5
  254. package/dist/routes/terminal/result.d.ts +5 -5
  255. package/dist/routes/terminal/result.js +7 -7
  256. package/dist/routes/terminal/route.d.ts +9 -9
  257. package/dist/routes/terminal/route.js +14 -14
  258. package/dist/routes/terminal/session.d.ts +5 -5
  259. package/dist/routes/terminal/session.js +7 -7
  260. package/dist/routes/terminal/trace.d.ts +2 -2
  261. package/dist/routes/terminal/types.d.ts +24 -24
  262. package/dist/routes/terminal/types.js +2 -2
  263. package/dist/run/bundle.d.ts +7 -7
  264. package/dist/run/bundle.js +2 -2
  265. package/dist/run/costs.d.ts +23 -0
  266. package/dist/run/costs.js +72 -43
  267. package/dist/run/dry-run-inputs.d.ts +1 -1
  268. package/dist/run/dry-run-inputs.js +1 -1
  269. package/dist/run/dry-run.js +2 -2
  270. package/dist/run/outcomes.d.ts +1 -1
  271. package/dist/run/participant.d.ts +1 -1
  272. package/dist/run/preflight-receipts.js +1 -1
  273. package/dist/run/pricing.js +2 -2
  274. package/dist/run/projection.d.ts +32 -32
  275. package/dist/run/projection.js +44 -44
  276. package/dist/run/reclaim.d.ts +1 -1
  277. package/dist/run/reclaim.js +1 -1
  278. package/dist/run/results.d.ts +2 -2
  279. package/dist/run/run-cost.d.ts +53 -0
  280. package/dist/run/run-cost.js +105 -0
  281. package/dist/run/run-index-analysis.d.ts +15 -0
  282. package/dist/run/run-index-analysis.js +77 -0
  283. package/dist/run/run-index.d.ts +11 -1
  284. package/dist/run/run-index.js +63 -49
  285. package/dist/run/run.d.ts +3 -3
  286. package/dist/run/run.js +2 -2
  287. package/dist/run/shared-world-evidence.d.ts +1 -1
  288. package/dist/run/shared-world-shape.js +1 -1
  289. package/dist/run/stats.d.ts +3 -3
  290. package/dist/run/stats.js +14 -14
  291. package/dist/run/status.d.ts +10 -2
  292. package/dist/run/status.js +6 -3
  293. package/dist/run/streams.d.ts +2 -2
  294. package/dist/run/study-provenance.d.ts +4 -2
  295. package/dist/run/study-provenance.js +7 -4
  296. package/dist/run/study-result.d.ts +0 -5
  297. package/dist/run/study-result.js +1 -1
  298. package/dist/run-study.d.ts +112 -0
  299. package/dist/{run-lab.js → run-study.js} +52 -45
  300. package/dist/{lab → study}/adapter-extension.d.ts +8 -20
  301. package/dist/{lab → study}/adapter-extension.js +2 -14
  302. package/dist/{lab → study}/adapter-scorer-loader.d.ts +10 -10
  303. package/dist/{lab → study}/adapter-scorer-loader.js +3 -3
  304. package/dist/study/composition-rules.d.ts +7 -0
  305. package/dist/{lab → study}/composition-rules.js +12 -12
  306. package/dist/study/config.d.ts +15 -0
  307. package/dist/{lab → study}/config.js +37 -20
  308. package/dist/study/convert.d.ts +1 -1
  309. package/dist/study/convert.js +15 -15
  310. package/dist/{lab → study}/device-presets.d.ts +2 -2
  311. package/dist/{lab → study}/discover.d.ts +29 -23
  312. package/dist/{lab → study}/discover.js +97 -118
  313. package/dist/{lab → study}/doctor.d.ts +11 -11
  314. package/dist/{lab → study}/doctor.js +18 -18
  315. package/dist/study/files.d.ts +2 -2
  316. package/dist/study/files.js +6 -5
  317. package/dist/{lab → study}/init-templates.d.ts +2 -2
  318. package/dist/{lab → study}/init-templates.js +16 -11
  319. package/dist/{lab → study}/init.d.ts +1 -1
  320. package/dist/{lab → study}/init.js +7 -4
  321. package/dist/{lab → study}/keys.d.ts +2 -2
  322. package/dist/{lab → study}/keys.js +10 -10
  323. package/dist/study/migrate.d.ts +8 -3
  324. package/dist/study/migrate.js +60 -4
  325. package/dist/{lab → study}/parse/actors.d.ts +5 -5
  326. package/dist/{lab → study}/parse/actors.js +5 -5
  327. package/dist/study/parse/comms.d.ts +12 -0
  328. package/dist/study/parse/execution.d.ts +19 -0
  329. package/dist/{lab → study}/parse/study-v3.d.ts +3 -5
  330. package/dist/{lab → study}/parse/study-v3.js +3 -3
  331. package/dist/{lab → study}/parse/subject-state.d.ts +8 -8
  332. package/dist/{lab → study}/parse/subject-state.js +4 -4
  333. package/dist/{lab → study}/parse/subject.d.ts +3 -3
  334. package/dist/{lab → study}/parse/subject.js +8 -8
  335. package/dist/{lab → study}/parse/values.d.ts +2 -2
  336. package/dist/{lab → study}/persona-resolve.d.ts +4 -4
  337. package/dist/{lab → study}/persona-resolve.js +2 -2
  338. package/dist/{lab → study}/plan-base.d.ts +7 -7
  339. package/dist/{lab → study}/plan-base.js +1 -1
  340. package/dist/{lab → study}/plan-participants.d.ts +10 -10
  341. package/dist/{lab → study}/plan-participants.js +4 -4
  342. package/dist/{lab → study}/plan-types.d.ts +28 -28
  343. package/dist/{lab → study}/plan-types.js +2 -2
  344. package/dist/study/plan.d.ts +13 -0
  345. package/dist/{lab → study}/plan.js +20 -20
  346. package/dist/study/preflight-probes.d.ts +3 -0
  347. package/dist/{lab → study}/preflight-probes.js +9 -8
  348. package/dist/study/preflight-result.d.ts +8 -0
  349. package/dist/{lab → study}/preflight-result.js +3 -3
  350. package/dist/{lab → study}/preflight.d.ts +31 -31
  351. package/dist/{lab → study}/preflight.js +8 -8
  352. package/dist/{lab → study}/requirements.d.ts +3 -3
  353. package/dist/{lab → study}/requirements.js +1 -1
  354. package/dist/study/route-inputs.d.ts +28 -0
  355. package/dist/{lab → study}/route-inputs.js +1 -1
  356. package/dist/{lab → study}/routing.d.ts +12 -12
  357. package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -10
  358. package/dist/{lab/run-lab-events.js → study/run-study-events.js} +4 -4
  359. package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +8 -17
  360. package/dist/study/run-study-homes.js +3 -0
  361. package/dist/study/run-study-options.d.ts +28 -0
  362. package/dist/{lab/run-lab-options.js → study/run-study-options.js} +16 -15
  363. package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +2 -2
  364. package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
  365. package/dist/{lab → study}/summary.d.ts +10 -10
  366. package/dist/{lab → study}/summary.js +15 -15
  367. package/dist/{lab → study}/tasks.d.ts +3 -3
  368. package/dist/{lab → study}/tasks.js +1 -1
  369. package/dist/{lab → study}/types.d.ts +104 -104
  370. package/dist/{lab → study}/types.js +1 -1
  371. package/dist/{lab → study}/validation.d.ts +19 -19
  372. package/dist/{lab → study}/validation.js +13 -13
  373. package/dist/{lab → study}/warnings.d.ts +4 -4
  374. package/dist/{lab → study}/warnings.js +1 -1
  375. package/dist/subject/clone.d.ts +6 -6
  376. package/dist/subject/clone.js +2 -2
  377. package/dist/subject/local-tree-archive.d.ts +2 -2
  378. package/dist/subject/local-tree-archive.js +3 -3
  379. package/dist/subject/local-tree.d.ts +3 -3
  380. package/dist/subject/runtime.js +2 -2
  381. package/dist/subject/serve.d.ts +4 -4
  382. package/dist/subject/state.d.ts +3 -3
  383. package/dist/subject/state.js +1 -1
  384. package/dist/subject/steps.d.ts +1 -1
  385. package/dist/subject/steps.js +1 -1
  386. package/dist/substrates/desktop-session.js +2 -2
  387. package/dist/substrates/detached.d.ts +1 -1
  388. package/dist/substrates/e2b/desktop-browser.d.ts +4 -4
  389. package/dist/substrates/e2b/desktop-browser.js +1 -1
  390. package/dist/substrates/e2b/desktop-cdp.d.ts +1 -1
  391. package/dist/substrates/e2b/desktop-cdp.js +1 -1
  392. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  393. package/dist/substrates/e2b/desktop-executor.js +12 -12
  394. package/dist/substrates/e2b/desktop-geometry.d.ts +1 -1
  395. package/dist/substrates/e2b/desktop-geometry.js +1 -1
  396. package/dist/substrates/e2b/desktop-media.d.ts +3 -3
  397. package/dist/substrates/e2b/lifetime.js +1 -1
  398. package/dist/substrates/e2b/sandbox.d.ts +3 -3
  399. package/dist/substrates/e2b/sandbox.js +1 -1
  400. package/dist/substrates/e2b/sdk.d.ts +1 -1
  401. package/dist/substrates/e2b/sdk.js +1 -1
  402. package/dist/substrates/local/runtime-config.d.ts +4 -4
  403. package/dist/substrates/local/runtime-config.js +4 -4
  404. package/dist/tui/contract.d.ts +8 -8
  405. package/dist/tui/contract.js +2 -2
  406. package/dist/tui/launch.d.ts +3 -3
  407. package/dist/tui/launch.js +22 -16
  408. package/dist/tui-app.js +139 -139
  409. package/dist/verify/subject.d.ts +1 -1
  410. package/dist/verify/subject.js +1 -1
  411. package/dist/verify/verify.js +2 -1
  412. package/docs/architecture/actor-contract.md +5 -5
  413. package/docs/architecture/browser-control.md +1 -1
  414. package/docs/architecture/external-public-shared-world.md +8 -7
  415. package/docs/architecture/github-feedback-loop.md +1 -1
  416. package/docs/architecture/task-protocol-support.md +1 -1
  417. package/docs/architecture/terminal-product-route.md +18 -18
  418. package/docs/contracts/adapter-fixtures.md +2 -2
  419. package/docs/contracts/errors.md +8 -8
  420. package/docs/contracts/run-bundle.md +6 -4
  421. package/docs/contracts/schemas.md +61 -42
  422. package/docs/contracts/study-analysis.md +4 -1
  423. package/docs/contracts/study-costs.md +17 -2
  424. package/examples/README.md +1 -1
  425. package/examples/scorer/scorer.mjs +3 -3
  426. package/package.json +2 -1
  427. package/skills/humanish/SKILL.md +8 -6
  428. package/skills/humanish/agents/openai.yaml +1 -1
  429. package/dist/cli/commands/lab-format.d.ts +0 -9
  430. package/dist/cli/commands/lab-route-run.d.ts +0 -19
  431. package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
  432. package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
  433. package/dist/cli/commands/lab-run.d.ts +0 -9
  434. package/dist/lab/composition-rules.d.ts +0 -7
  435. package/dist/lab/config.d.ts +0 -7
  436. package/dist/lab/deprecated-fields.d.ts +0 -10
  437. package/dist/lab/deprecated-fields.js +0 -24
  438. package/dist/lab/parse/comms.d.ts +0 -12
  439. package/dist/lab/parse/execution.d.ts +0 -19
  440. package/dist/lab/plan.d.ts +0 -13
  441. package/dist/lab/preflight-probes.d.ts +0 -3
  442. package/dist/lab/preflight-result.d.ts +0 -8
  443. package/dist/lab/route-inputs.d.ts +0 -28
  444. package/dist/lab/run-lab-homes.js +0 -7
  445. package/dist/lab/run-lab-options.d.ts +0 -28
  446. package/dist/library-aliases.d.ts +0 -56
  447. package/dist/library-aliases.js +0 -22
  448. package/dist/run-lab.d.ts +0 -112
  449. /package/dist/{lab → study}/device-presets.js +0 -0
  450. /package/dist/{lab → study}/init-paths.d.ts +0 -0
  451. /package/dist/{lab → study}/init-paths.js +0 -0
  452. /package/dist/{lab → study}/init-plan.d.ts +0 -0
  453. /package/dist/{lab → study}/init-plan.js +0 -0
  454. /package/dist/{lab → study}/parse/comms.js +0 -0
  455. /package/dist/{lab → study}/parse/execution.js +0 -0
  456. /package/dist/{lab → study}/parse/values.js +0 -0
  457. /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
  458. /package/dist/{lab → study}/participant-assignment.js +0 -0
  459. /package/dist/{lab → study}/persona.d.ts +0 -0
  460. /package/dist/{lab → study}/persona.js +0 -0
  461. /package/dist/{lab → study}/routing.js +0 -0
@@ -18,6 +18,7 @@ import { TERMINAL_RUNTIME_VERSION_TIMEOUT_MS, buildRuntimeExecPrefix, buildRunti
18
18
  import { runWithWallClock, teardownSandbox } from "./sandbox.js";
19
19
  import { DEFAULT_REQUEST_TIMEOUT_MS, PRODUCT_SETUP_TIMEOUT_MS, SANDBOX_WORKDIR, UPLOAD_MAX_BYTES, } from "./types.js";
20
20
  import { terminalSandboxTimeoutMs } from "./lifetime.js";
21
+ import { plural } from "../../run/text.js";
21
22
  export class LiveTerminalSandbox {
22
23
  status = "failed";
23
24
  completionReason = "harness_error";
@@ -109,7 +110,7 @@ export class LiveTerminalSandbox {
109
110
  // able to reach, without the ledger carrying any secret.
110
111
  recordLifecycle("terminal-lab.egress.policy", egressAllow === undefined
111
112
  ? "Egress is unrestricted (no execution.egressAllow declared)."
112
- : `Egress routing allowlist: ${egressAllow.length} declared host(s): ${egressAllow.join(", ")}; deny-all fallback. Domain routing is not strict destination isolation on shared infrastructure.`);
113
+ : `Egress routing allowlist: ${plural(egressAllow.length, "declared host")}: ${egressAllow.join(", ")}; deny-all fallback. Domain routing is not strict destination isolation on shared infrastructure.`);
113
114
  recordLifecycle("terminal-lab.runtime-auth", runtimeEnv.mode === "openai-egress"
114
115
  ? "Runtime auth openai-egress: raw key remains outside the sandbox in the api.openai.com HTTPS Authorization transform; Codex receives an inert CODEX_API_KEY placeholder and the default OpenAI endpoint. Every sandbox process, including bootstrap/setup, can spend via this proxy; no added routing restriction or provider spending limit."
115
116
  : `Runtime auth openai-env: raw key from ${runtimeEnv.keyName} is passed command-scoped to Codex and inherited by its child processes.`);
@@ -207,7 +208,7 @@ export class LiveTerminalSandbox {
207
208
  // Same channel and same guarantees as the runtime bootstrap above: no runtime key touches it,
208
209
  // and a failure fails the run closed rather than handing the agent a half-built world. It
209
210
  // exists so a study can put the participant in a prepared project: asking an agent what
210
- // studies a project contains, in an empty directory, measures the lab and not the product
211
+ // studies a project contains, in an empty directory, measures the study and not the product
211
212
  // (learned the hard way on the desktop route, labs/tui-self-study.yaml).
212
213
  const install = plan.product.install;
213
214
  if (install === undefined)
@@ -1,5 +1,6 @@
1
1
  import { normalizeLocalActorTranscript } from "../../run/terminal-contract.js";
2
2
  import { MESSAGE_CHARS, PENDING_LINE_CHARS, TEXT_ITEMS_BYTES, TEXT_ITEMS_MAX } from "./types.js";
3
+ import { plural } from "../../run/text.js";
3
4
  const itemEvents = new Set(["item.started", "item.updated", "item.completed"]);
4
5
  const nonempty = (value) => typeof value === "string" && value.trim().length > 0;
5
6
  const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
@@ -148,7 +149,7 @@ export function createTerminalParticipantReader(sanitize) {
148
149
  if (droppedLines > 0)
149
150
  notices.push([
150
151
  "agent output lines skipped",
151
- `Skipped ${droppedLines} stdout line(s) that ran past ${PENDING_LINE_CHARS} characters without a newline. Items on those lines are not in this trace or its counts.`,
152
+ `Skipped ${plural(droppedLines, "stdout line")} that ran past ${PENDING_LINE_CHARS} characters without a newline. Items on those lines are not in this trace or its counts.`,
152
153
  ]);
153
154
  notices.forEach(([title, text], index) => items.push({
154
155
  id: `notice-${String(index + 1).padStart(3, "0")}`,
@@ -1,6 +1,6 @@
1
1
  import type { ActorPersonaRef } from "../../actors/contract.js";
2
- import { type ResolvedPersona } from "../../lab/persona.js";
3
- import type { TerminalPlan } from "../../lab/plan-types.js";
2
+ import { type ResolvedPersona } from "../../study/persona.js";
3
+ import type { TerminalPlan } from "../../study/plan-types.js";
4
4
  /** A terminal run's persona, resolved against the project's committed persona files. */
5
5
  export interface TerminalPersona {
6
6
  personaId: string;
@@ -3,8 +3,8 @@
3
3
  // record come from one place. Each path keeps its own prompt and its own set of scrubbed secrets.
4
4
  import { realpath } from "node:fs/promises";
5
5
  import path from "node:path";
6
- import { personaBrief, personaToDirectives, renderPersonaPromptSection, } from "../../lab/persona.js";
7
- import { resolveCommittedPersona } from "../../lab/persona-resolve.js";
6
+ import { personaBrief, personaToDirectives, renderPersonaPromptSection, } from "../../study/persona.js";
7
+ import { resolveCommittedPersona } from "../../study/persona-resolve.js";
8
8
  import { prepareSelectedOutputDirectory } from "../../run/contained-output.js";
9
9
  /** Resolves the plan's persona; the resolver's warnings go into `warnings`. */
10
10
  export async function resolveTerminalPersona(args) {
@@ -1,16 +1,16 @@
1
- import type { RoutePlanResult, RouteRefusal, TerminalPlan } from "../../lab/plan-types.js";
2
- import type { LabConfig } from "../../lab/types.js";
3
- import { type TerminalProductLabResult } from "./types.js";
4
- /** The error a terminal lab returns before a run starts. `actor` names the registered actor. */
5
- export interface TerminalRefusal extends RouteRefusal<"terminal", NonNullable<TerminalProductLabResult["error"]>["code"]> {
1
+ import type { RoutePlanResult, RouteRefusal, TerminalPlan } from "../../study/plan-types.js";
2
+ import type { StudyConfig } from "../../study/types.js";
3
+ import { type TerminalProductStudyResult } from "./types.js";
4
+ /** The error a terminal study returns before a run starts. `actor` names the registered actor. */
5
+ export interface TerminalRefusal extends RouteRefusal<"terminal", NonNullable<TerminalProductStudyResult["error"]>["code"]> {
6
6
  readonly actor?: string;
7
7
  }
8
8
  export type TerminalPlanResult = RoutePlanResult<TerminalPlan, TerminalRefusal>;
9
9
  /**
10
- * Plan a terminal-product lab. It is called for any config handed to the terminal runner, not
10
+ * Plan a terminal-product study. It is called for any config handed to the terminal runner, not
11
11
  * only one routeOf sends here, so a config for another route gets this route's refusal.
12
12
  */
13
- export declare function planTerminalLab(config: LabConfig, input: {
13
+ export declare function planTerminalStudy(config: StudyConfig, input: {
14
14
  readonly dryRun: boolean;
15
15
  /** A test's costProbe can measure spend lines, so a positive maxUsd can trip. */
16
16
  readonly hasCostProbe?: boolean;
@@ -5,24 +5,24 @@ import { DEFAULT_OPENAI_CU_MODEL } from "../../actors/computer-use/openai-provid
5
5
  import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
6
6
  import { isReasoningEffort } from "../../actors/reasoning-effort.js";
7
7
  import { actorRegistry, isTerminalActorDescriptor } from "../../actors/registry.js";
8
- import { isNonEmpty, planBase } from "../../lab/plan-base.js";
9
- import { desktopMediaValidationReason, taskProtocolValidationReason, } from "../../lab/validation.js";
8
+ import { isNonEmpty, planBase } from "../../study/plan-base.js";
9
+ import { desktopMediaValidationReason, taskProtocolValidationReason, } from "../../study/validation.js";
10
10
  import { MAX_SANDBOX_MS } from "../../substrates/e2b/lifetime.js";
11
11
  import { NODE_BOOTSTRAP_TIMEOUT_MS } from "../../subject/node-bootstrap.js";
12
12
  import { terminalSandboxTimeoutMs } from "./lifetime.js";
13
13
  import { isExactRuntimeVersion, TERMINAL_RUNTIME_VERSION_TIMEOUT_MS } from "./runtime.js";
14
14
  import { PRODUCT_SETUP_TIMEOUT_MS, TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS, } from "./types.js";
15
15
  /**
16
- * Plan a terminal-product lab. It is called for any config handed to the terminal runner, not
16
+ * Plan a terminal-product study. It is called for any config handed to the terminal runner, not
17
17
  * only one routeOf sends here, so a config for another route gets this route's refusal.
18
18
  */
19
- export function planTerminalLab(config, input) {
19
+ export function planTerminalStudy(config, input) {
20
20
  const refuse = (code, message, actor) => ({
21
21
  ok: false,
22
22
  refusal: { route: "terminal", code, message, ...(actor === undefined ? {} : { actor }) },
23
23
  });
24
24
  if (String(config.comms?.email?.kind) === "real")
25
- return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", "Real email receiving is unsupported on the terminal route. Use a supported hosted computer-use browser lab.");
25
+ return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", "Real email receiving is unsupported on the terminal route. Use a supported hosted computer-use browser study.");
26
26
  const mediaReason = desktopMediaValidationReason(config);
27
27
  if (mediaReason)
28
28
  return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", mediaReason);
@@ -1,7 +1,7 @@
1
1
  import type { ObserverResult } from "../../observer/render.js";
2
2
  import type { ActorCompletionReason, ActorStatus, ActorTrace } from "../../actors/contract.js";
3
3
  import { type ExecutionFailure, type ExecutionOutcome, type Judgment, type ParticipantFacts } from "../../run/judge.js";
4
- import { type NoSpendProof, type TerminalCostLedger, type TerminalLedgers, type TerminalProductLabResult } from "./types.js";
4
+ import { type NoSpendProof, type TerminalCostLedger, type TerminalLedgers, type TerminalProductStudyResult } from "./types.js";
5
5
  /**
6
6
  * What judge.ts reads from a finished terminal session, after a blown cap has overridden it. It has
7
7
  * no engagement or blocker rule: the agent's nonce-verified marker is its declared outcome.
@@ -20,10 +20,10 @@ export declare function terminalExecutionFailures(args: {
20
20
  cleanup: TerminalLedgers["cleanup"];
21
21
  observer: Pick<ObserverResult, "ok" | "error">;
22
22
  }): ExecutionFailure[];
23
- /** The terminal-product lab result for a live run, from its session, cleanup and cost ledger. */
24
- export declare function terminalLabResult(args: {
23
+ /** The terminal-product study result for a live run, from its session, cleanup and cost ledger. */
24
+ export declare function terminalStudyResult(args: {
25
25
  cwd: string;
26
- labId: string;
26
+ studyId: string;
27
27
  actorId: string;
28
28
  productName: string;
29
29
  runId: string;
@@ -44,4 +44,4 @@ export declare function terminalLabResult(args: {
44
44
  execution: ExecutionOutcome;
45
45
  observer: ObserverResult;
46
46
  warnings: string[];
47
- }): TerminalProductLabResult;
47
+ }): TerminalProductStudyResult;
@@ -39,17 +39,17 @@ export function terminalExecutionFailures(args) {
39
39
  : [
40
40
  {
41
41
  kind: "evidence",
42
- message: observer.error?.message ?? "Observer failed for the terminal-product lab run.",
42
+ message: observer.error?.message ?? "Observer failed for the terminal-product run.",
43
43
  },
44
44
  ]),
45
45
  ];
46
46
  }
47
- /** The terminal-product lab result for a live run, from its session, cleanup and cost ledger. */
48
- export function terminalLabResult(args) {
49
- const { cwd, labId, actorId, productName, runId, sessionStatus, completionReason, sessionReason, sessionError, sandboxId, cleanup, cost, noSpendProof, capFailure, declaredScorerFailure, judgment, execution, observer, warnings, } = args;
50
- // The lab's exit code: verified evidence, no harness error and proven cleanup. A blocked/
47
+ /** The terminal-product study result for a live run, from its session, cleanup and cost ledger. */
48
+ export function terminalStudyResult(args) {
49
+ const { cwd, studyId, actorId, productName, runId, sessionStatus, completionReason, sessionReason, sessionError, sandboxId, cleanup, cost, noSpendProof, capFailure, declaredScorerFailure, judgment, execution, observer, warnings, } = args;
50
+ // The run's exit code: verified evidence, no harness error and proven cleanup. A blocked/
51
51
  // timed-out agent run is still ok-as-evidence at the bundle level (the failure is the evidence),
52
- // but the lab result surfaces ok:false on a harness error or unproven teardown (fail-closed).
52
+ // but the study result surfaces ok:false on a harness error or unproven teardown (fail-closed).
53
53
  // remaining===0 is the by-id-confirmed-reclaimed state; remaining===1 (still present) and
54
54
  // remaining===-1 (kill(id) itself failed) are both unproven by design.
55
55
  const cleanupProven = cleanup.killed && cleanup.remaining === 0;
@@ -63,7 +63,7 @@ export function terminalLabResult(args) {
63
63
  policy: OUTCOME_POLICIES.terminal,
64
64
  });
65
65
  return {
66
- ...studyResultIdentity("terminal", labId),
66
+ ...studyResultIdentity("terminal", studyId),
67
67
  ok,
68
68
  cwd,
69
69
  actor: actorId,
@@ -1,22 +1,22 @@
1
1
  import { type TerminalRefusal } from "./plan.js";
2
- import type { TerminalPlan } from "../../lab/plan-types.js";
3
- import type { AdmittedPlan } from "../../run-lab.js";
4
- import { type RunTerminalProductLabOptions, type TerminalProductLabResult, type TerminalRunInput } from "./types.js";
2
+ import type { TerminalPlan } from "../../study/plan-types.js";
3
+ import type { AdmittedPlan } from "../../run-study.js";
4
+ import { type RunTerminalProductStudyOptions, type TerminalProductStudyResult, type TerminalRunInput } from "./types.js";
5
5
  /**
6
6
  * The config-taking entry point. It plans, returns a refusal with the same envelope and analysis
7
7
  * record the route has always returned, and otherwise runs the plan.
8
8
  */
9
- export declare function runTerminalProductLab(options: RunTerminalProductLabOptions): Promise<TerminalProductLabResult>;
10
- /** A refused terminal lab's result: the route's envelope, and the analysis record a refusal gets. */
11
- export declare function terminalLabRefusal(options: RunTerminalProductLabOptions, refusal: TerminalRefusal): Promise<TerminalProductLabResult>;
9
+ export declare function runTerminalProductStudy(options: RunTerminalProductStudyOptions): Promise<TerminalProductStudyResult>;
10
+ /** A refused terminal study's result: the route's envelope, and the analysis record a refusal gets. */
11
+ export declare function terminalStudyRefusal(options: RunTerminalProductStudyOptions, refusal: TerminalRefusal): Promise<TerminalProductStudyResult>;
12
12
  /**
13
13
  * Run a terminal plan. The run scope gives a direct library caller the same run lifetime the CLI
14
- * gets: whichever of its fail-closed exits the lab takes, the run it started is closed, and only a
14
+ * gets: whichever of its fail-closed exits the run takes, the run it started is closed, and only a
15
15
  * run that published its final bundle reaches automatic analysis.
16
16
  */
17
- export declare function runTerminalPlan(plan: TerminalPlan, input: TerminalRunInput): Promise<TerminalProductLabResult>;
17
+ export declare function runTerminalPlan(plan: TerminalPlan, input: TerminalRunInput): Promise<TerminalProductStudyResult>;
18
18
  /**
19
- * runLab's step for a terminal plan. It runs a live plan's local checks (checkLiveTerminalMachine)
19
+ * runStudyWith's step for a terminal plan. It runs a live plan's local checks (checkLiveTerminalMachine)
20
20
  * before any run scope opens, so the CLI can present their refusal before it loads a declared
21
21
  * scorer, and returns the run that continues from them with that scorer.
22
22
  */
@@ -1,6 +1,6 @@
1
1
  // The terminal-product route: a real autonomous agent (Codex) studies a CLI or product from its
2
2
  // public surfaces only, inside an E2B shell. The flow:
3
- // 1. admit: planTerminalLab refuses what the plan cannot hold, then a live plan's machine checks
3
+ // 1. admit: planTerminalStudy refuses what the plan cannot hold, then a live plan's machine checks
4
4
  // (checkLiveTerminalMachine) run before any run scope opens, so the CLI can refuse before it
5
5
  // loads a declared scorer;
6
6
  // 2. open the run scope;
@@ -47,29 +47,29 @@ import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
47
47
  import { completeAutomaticAnalysis } from "../../analysis/automatic-completion.js";
48
48
  import path from "node:path";
49
49
  import { runScope } from "../../run/run.js";
50
- import { planTerminalLab } from "./plan.js";
51
- import { runDryTerminalLab } from "./dry-run.js";
50
+ import { planTerminalStudy } from "./plan.js";
51
+ import { runDryTerminalStudy } from "./dry-run.js";
52
52
  import { checkLiveTerminalMachine, runLiveTerminalSession } from "./session.js";
53
- import { terminalRouteScorer } from "../../lab/adapter-scorer-loader.js";
54
- import { withLateScorer } from "../../lab/route-inputs.js";
53
+ import { terminalRouteScorer } from "../../study/adapter-scorer-loader.js";
54
+ import { withLateScorer } from "../../study/route-inputs.js";
55
55
  import {} from "./types.js";
56
56
  import { studyResultIdentity } from "../../run/study-result.js";
57
57
  /**
58
58
  * The config-taking entry point. It plans, returns a refusal with the same envelope and analysis
59
59
  * record the route has always returned, and otherwise runs the plan.
60
60
  */
61
- export async function runTerminalProductLab(options) {
61
+ export async function runTerminalProductStudy(options) {
62
62
  const { config, dryRun, ...input } = options;
63
- const planned = planTerminalLab(config, {
63
+ const planned = planTerminalStudy(config, {
64
64
  dryRun,
65
65
  hasCostProbe: input.deps?.costProbe !== undefined,
66
66
  });
67
67
  if (planned.ok)
68
68
  return runTerminalPlan(planned.plan, input);
69
- return terminalLabRefusal(options, planned.refusal);
69
+ return terminalStudyRefusal(options, planned.refusal);
70
70
  }
71
- /** A refused terminal lab's result: the route's envelope, and the analysis record a refusal gets. */
72
- export function terminalLabRefusal(options, refusal) {
71
+ /** A refused terminal study's result: the route's envelope, and the analysis record a refusal gets. */
72
+ export function terminalStudyRefusal(options, refusal) {
73
73
  const { config, dryRun } = options;
74
74
  const refused = {
75
75
  ...studyResultIdentity("terminal", config.id),
@@ -88,7 +88,7 @@ export function terminalLabRefusal(options, refusal) {
88
88
  }
89
89
  /**
90
90
  * Run a terminal plan. The run scope gives a direct library caller the same run lifetime the CLI
91
- * gets: whichever of its fail-closed exits the lab takes, the run it started is closed, and only a
91
+ * gets: whichever of its fail-closed exits the run takes, the run it started is closed, and only a
92
92
  * run that published its final bundle reaches automatic analysis.
93
93
  */
94
94
  export async function runTerminalPlan(plan, input) {
@@ -96,7 +96,7 @@ export async function runTerminalPlan(plan, input) {
96
96
  return admission.ok ? runAdmittedTerminalRun(admission.admitted, input) : admission.result;
97
97
  }
98
98
  /**
99
- * runLab's step for a terminal plan. It runs a live plan's local checks (checkLiveTerminalMachine)
99
+ * runStudyWith's step for a terminal plan. It runs a live plan's local checks (checkLiveTerminalMachine)
100
100
  * before any run scope opens, so the CLI can present their refusal before it loads a declared
101
101
  * scorer, and returns the run that continues from them with that scorer.
102
102
  */
@@ -141,7 +141,7 @@ function completeTerminalAnalysis(plan, input, result, finished) {
141
141
  function terminalFailure(plan, input, warnings) {
142
142
  const cwd = path.resolve(input.cwd);
143
143
  return (code, message) => ({
144
- ...studyResultIdentity("terminal", plan.labId),
144
+ ...studyResultIdentity("terminal", plan.studyId),
145
145
  ok: false,
146
146
  cwd,
147
147
  actor: plan.actor,
@@ -165,5 +165,5 @@ async function runTerminalPlanInScope(admitted, input, scope) {
165
165
  const { plan, runtimeEnv } = admitted;
166
166
  return runLiveTerminalSession({ plan, input, cwd, warnings, failed, scope, runtimeEnv });
167
167
  }
168
- return runDryTerminalLab({ plan: admitted.plan, input, cwd, warnings, failed, scope });
168
+ return runDryTerminalStudy({ plan: admitted.plan, input, cwd, warnings, failed, scope });
169
169
  }
@@ -1,4 +1,4 @@
1
- import type { LiveTerminalAuth, LiveTerminalPlan, RunLiveTerminalSessionArgs, TerminalProductLabErrorCode, TerminalProductLabResult, TerminalRunInput } from "./types.js";
1
+ import type { LiveTerminalAuth, LiveTerminalPlan, RunLiveTerminalSessionArgs, TerminalProductStudyErrorCode, TerminalProductStudyResult, TerminalRunInput } from "./types.js";
2
2
  /**
3
3
  * The checks of this machine a live run makes before its run starts: the runtime key and
4
4
  * E2B_API_KEY. They read only the plan and the environment, so the CLI makes them before it loads
@@ -9,17 +9,17 @@ export declare function checkLiveTerminalMachine(plan: LiveTerminalPlan, input:
9
9
  readonly runtimeEnv: LiveTerminalAuth;
10
10
  } | {
11
11
  readonly ok: false;
12
- readonly code: TerminalProductLabErrorCode;
12
+ readonly code: TerminalProductStudyErrorCode;
13
13
  readonly message: string;
14
14
  };
15
15
  /**
16
- * The live in-sandbox agent session orchestrator (mirror of runCuaActorLab's E2B branch). Enforces
16
+ * The live in-sandbox agent session orchestrator (mirror of runCuaActorStudy's E2B branch). Enforces
17
17
  * the 8-point safety contract by construction; fails closed before any sandbox/key/spend on any
18
18
  * precondition miss. Persists the substrate-lifecycle/command-log/interventions/cleanup ledgers,
19
19
  * the redacted terminal event stream + normalized transcript, the agent report, and the
20
20
  * provider-neutral actor trace; tears the sandbox down in a finally and proves the teardown.
21
21
  */
22
- export declare function runLiveTerminalSession(args: RunLiveTerminalSessionArgs): Promise<TerminalProductLabResult>;
23
- /** The default mission when the lab omits one. Public-safe, product-neutral author text. */
22
+ export declare function runLiveTerminalSession(args: RunLiveTerminalSessionArgs): Promise<TerminalProductStudyResult>;
23
+ /** The default mission when the study omits one. Public-safe, product-neutral author text. */
24
24
  export declare function defaultMission(productName: string): string;
25
25
  export declare function makeTerminalRunId(): string;
@@ -1,5 +1,5 @@
1
1
  import { randomBytes, randomUUID } from "node:crypto";
2
- import { missingKeys } from "../../lab/requirements.js";
2
+ import { missingKeys } from "../../study/requirements.js";
3
3
  import { declaredRuntimeProvenance } from "./runtime.js";
4
4
  import { digestText, redactText, scrubLiterals } from "../../evidence/redaction.js";
5
5
  import { describeMissingKeys } from "../../keys/key-resolution.js";
@@ -18,7 +18,7 @@ import { finishLiveTerminalSession } from "./live-finish.js";
18
18
  export function checkLiveTerminalMachine(plan, input, warnings) {
19
19
  const env = input.env ?? process.env;
20
20
  const { maxUsd } = plan.caps;
21
- // planTerminalLab refuses a positive maxUsd without a costProbe, so one is present here.
21
+ // planTerminalStudy refuses a positive maxUsd without a costProbe, so one is present here.
22
22
  if (maxUsd > 0) {
23
23
  warnings.push(`scenario.caps.maxUsd=${maxUsd} is checked after the session against the lines the costProbe measures; lines it leaves null (unmeasured) never trip it. scenario.caps.maxMinutes bounds the run while it runs.`);
24
24
  }
@@ -32,13 +32,13 @@ export function checkLiveTerminalMachine(plan, input, warnings) {
32
32
  return {
33
33
  ok: false,
34
34
  code: "HUMANISH_TERMINAL_KEYS_MISSING",
35
- message: `Live terminal-product labs need E2B_API_KEY in the environment (values are never persisted). ${describeMissingKeys(["E2B_API_KEY"], env)}`,
35
+ message: `Live terminal-product studies need E2B_API_KEY in the environment (values are never persisted). ${describeMissingKeys(["E2B_API_KEY"], env)}`,
36
36
  };
37
37
  }
38
38
  return { ok: true, runtimeEnv };
39
39
  }
40
40
  /**
41
- * The live in-sandbox agent session orchestrator (mirror of runCuaActorLab's E2B branch). Enforces
41
+ * The live in-sandbox agent session orchestrator (mirror of runCuaActorStudy's E2B branch). Enforces
42
42
  * the 8-point safety contract by construction; fails closed before any sandbox/key/spend on any
43
43
  * precondition miss. Persists the substrate-lifecycle/command-log/interventions/cleanup ledgers,
44
44
  * the redacted terminal event stream + normalized transcript, the agent report, and the
@@ -61,7 +61,7 @@ export async function runLiveTerminalSession(args) {
61
61
  mintRunId: makeTerminalRunId,
62
62
  // This entry point is the live terminal route; its dry-run sibling is a separate function.
63
63
  mode: "live",
64
- lab: plan.lab,
64
+ study: plan.study,
65
65
  renderReview: renderTerminalReviewMarkdown,
66
66
  observer: { open: input.open === true, render: deps.renderObserver },
67
67
  now,
@@ -101,7 +101,7 @@ export async function runLiveTerminalSession(args) {
101
101
  maxMinutes,
102
102
  e2bApiKey,
103
103
  runPaths,
104
- metadata: buildSandboxMetadata({ labId: plan.labId, recordId: "sim-001", runId }),
104
+ metadata: buildSandboxMetadata({ studyId: plan.studyId, recordId: "sim-001", runId }),
105
105
  warnings,
106
106
  recorder,
107
107
  });
@@ -192,7 +192,7 @@ function composeLivePrompt(args) {
192
192
  `When finished, print exactly one final machine-readable line in this format: HUMANISH_ACTOR_VERDICT=<status> HUMANISH_ACTOR_NONCE=${args.verdictNonce} where <status> is passed, blocked, or failed.`,
193
193
  ].join("\n");
194
194
  }
195
- /** The default mission when the lab omits one. Public-safe, product-neutral author text. */
195
+ /** The default mission when the study omits one. Public-safe, product-neutral author text. */
196
196
  export function defaultMission(productName) {
197
197
  return `You are an autonomous agent. Discover ${productName} from its public surfaces and determine whether it can help with a durable real task. Stay within the declared no-spend caps. Leave feedback if the workflow is confusing.`;
198
198
  }
@@ -1,5 +1,5 @@
1
1
  import type { ActorCompletionReason, ActorPersonaRef, ActorRuntimeProvenance, ActorStatus, ActorTokenUsage, ActorTrace } from "../../actors/contract.js";
2
- import type { LabRuntimeAuth } from "../../lab/types.js";
2
+ import type { StudyRuntimeAuth } from "../../study/types.js";
3
3
  import type { TerminalParticipantText } from "./participant-text.js";
4
4
  import { type CommandLogRecord, type TerminalEventRecord } from "./types.js";
5
5
  /**
@@ -27,7 +27,7 @@ export declare function buildTerminalActorTrace(args: {
27
27
  terminalEvents: TerminalEventRecord[];
28
28
  commandLog: CommandLogRecord[];
29
29
  transcriptTail: string;
30
- runtimeAuth: LabRuntimeAuth;
30
+ runtimeAuth: StudyRuntimeAuth;
31
31
  runtime: ActorRuntimeProvenance;
32
32
  /** Runtime-turn aggregate usage parsed from the exec stream. Absent when the stream
33
33
  * carried no usage record, which stays distinct from a measured zero. */
@@ -1,17 +1,17 @@
1
- import type { LabEvent } from "../../lab/run-lab-events.js";
1
+ import type { StudyEvent } from "../../study/run-study-events.js";
2
2
  import { type AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
3
3
  import type { ActorCompletionReason, ActorRuntimeProvenance, ActorStatus, ActorTrace } from "../../actors/contract.js";
4
4
  import type { CostCategory } from "../../run/terminal-contract.js";
5
5
  import type { RunScope } from "../../run/run.js";
6
6
  import type { buildRuntimeAuth } from "./credentials.js";
7
- import type { TerminalPlan } from "../../lab/plan-types.js";
8
- import type { LabDeps } from "../../lab/lab-deps.js";
9
- import type { LabConfig } from "../../lab/types.js";
7
+ import type { TerminalPlan } from "../../study/plan-types.js";
8
+ import type { StudyDeps } from "../../study/study-deps.js";
9
+ import type { StudyConfig } from "../../study/types.js";
10
10
  import type { ObserverResult } from "../../observer/render.js";
11
11
  import { type RunAdapterScore, type RunBundle, type RunFeedbackCandidate, type RunScorerProvenance } from "../../run/bundle.js";
12
12
  import { type StudyResultIdentity } from "../../run/study-result.js";
13
- /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
14
- export declare const TERMINAL_PRODUCT_LAB_PROVIDER_METADATA: {
13
+ /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_STUDY_PROVIDER_METADATA). */
14
+ export declare const TERMINAL_PRODUCT_STUDY_PROVIDER_METADATA: {
15
15
  readonly mode: "terminal-product-lab";
16
16
  readonly tool: "humanish";
17
17
  };
@@ -61,20 +61,20 @@ export interface TerminalProductScoringContext {
61
61
  transcript: string;
62
62
  /** The studied product name (public-safe). */
63
63
  product: string;
64
- /** The lab id (the run's scenario scope). */
65
- labId: string;
64
+ /** The study id (the run's scenario scope). */
65
+ studyId: string;
66
66
  /** The run id (for building namespaced idempotency keys + evidence pointers). */
67
67
  runId: string;
68
68
  }
69
69
  /**
70
70
  * Known spend lines for the terminal cost ledger. Core has no product, media or payment spend
71
71
  * signal, so it fills only the provider line from trace tokenUsage when present. A test injects
72
- * known lines through `LabDeps.costProbe`; absent signals keep the null-discipline default.
72
+ * known lines through `StudyDeps.costProbe`; absent signals keep the null-discipline default.
73
73
  */
74
74
  export type TerminalCostProbe = (context: {
75
75
  tokenCostUsd?: number;
76
76
  }) => Partial<Record<"product" | "media" | "payment" | "provider", CostLine>> | undefined;
77
- /** The scorer functions a terminal run calls: `RunLabOptions.scorer` without `deriveArtifacts`. */
77
+ /** The scorer functions a terminal run calls: `RunStudyOptions.scorer` without `deriveArtifacts`. */
78
78
  export interface TerminalScorer {
79
79
  /**
80
80
  * The adapter extension seam: product-adapter hooks without forking
@@ -97,13 +97,13 @@ export interface TerminalScorer {
97
97
  */
98
98
  deriveFeedback?: (ctx: TerminalProductScoringContext) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
99
99
  }
100
- export interface RunTerminalProductLabOptions {
100
+ export interface RunTerminalProductStudyOptions {
101
101
  /** Cancels post-run analysis only. */
102
102
  analysisSignal?: AbortSignal;
103
- /** Reports the analysis window to onEvent; built by normalizeRunLabOptions. */
104
- emit?: (event: LabEvent) => void;
103
+ /** Reports the analysis window to onEvent; built by normalizeRunStudyOptions. */
104
+ emit?: (event: StudyEvent) => void;
105
105
  cwd: string;
106
- config: LabConfig;
106
+ config: StudyConfig;
107
107
  /** Resolved upstream (scenario.mode + CLI override); defaults safe (dry-run). */
108
108
  dryRun: boolean;
109
109
  open?: boolean;
@@ -117,7 +117,7 @@ export interface RunTerminalProductLabOptions {
117
117
  env?: Readonly<Record<string, string | undefined>>;
118
118
  scorer?: TerminalScorer;
119
119
  /** Test seams: the E2B module, the Observer renderer, the clock and the cost probe. */
120
- deps?: LabDeps;
120
+ deps?: StudyDeps;
121
121
  /**
122
122
  * Present only when the scorer was config-declared and loaded by the CLI. Its presence
123
123
  * is the "declared" marker: a config-declared terminal scorer returning status:"fail" flips
@@ -127,10 +127,10 @@ export interface RunTerminalProductLabOptions {
127
127
  */
128
128
  scorerProvenance?: RunScorerProvenance;
129
129
  }
130
- export interface TerminalProductLabResult extends AutomaticAnalysisResult, StudyResultIdentity<"terminal"> {
130
+ export interface TerminalProductStudyResult extends AutomaticAnalysisResult, StudyResultIdentity<"terminal"> {
131
131
  /** True when the bundle verified and (dry-run, or the live session reached a terminal verdict
132
132
  * without a harness error + cleanup was proven). The agent's pass/fail is evidence, not the
133
- * lab's exit code. */
133
+ * run's exit code. */
134
134
  ok: boolean;
135
135
  cwd: string;
136
136
  /** The registry-resolved actor id that ran (or would run) the session. */
@@ -171,7 +171,7 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult, Study
171
171
  observer?: ObserverResult;
172
172
  warnings: string[];
173
173
  error?: {
174
- code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_TERMINAL_FAILED" | "HUMANISH_TERMINAL_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_SUBJECT_INVALID" | "HUMANISH_TERMINAL_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_KEYS_MISSING" | "HUMANISH_TERMINAL_CAPS_MISSING" | "HUMANISH_TERMINAL_CAPS_INVALID" | "HUMANISH_TERMINAL_UNPRICED_CAP" | "HUMANISH_TERMINAL_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE";
174
+ code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_STUDY_V2_UNSUPPORTED" | "HUMANISH_TERMINAL_FAILED" | "HUMANISH_TERMINAL_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_SUBJECT_INVALID" | "HUMANISH_TERMINAL_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_KEYS_MISSING" | "HUMANISH_TERMINAL_CAPS_MISSING" | "HUMANISH_TERMINAL_CAPS_INVALID" | "HUMANISH_TERMINAL_UNPRICED_CAP" | "HUMANISH_TERMINAL_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE";
175
175
  message: string;
176
176
  };
177
177
  }
@@ -309,13 +309,13 @@ export interface TerminalLedgers {
309
309
  /** The no-spend proof derived from `cost`. Never an independent assertion. */
310
310
  noSpendProof: NoSpendProof;
311
311
  }
312
- /** What a terminal run takes besides its plan. The plan carries the config, dry run and lab. */
313
- export type TerminalRunInput = Omit<RunTerminalProductLabOptions, "config" | "dryRun" | "lab">;
314
- /** A live terminal plan: its caps are the fail-closed ones planTerminalLab required. */
312
+ /** What a terminal run takes besides its plan. The plan carries the config, dry run and study. */
313
+ export type TerminalRunInput = Omit<RunTerminalProductStudyOptions, "config" | "dryRun">;
314
+ /** A live terminal plan: its caps are the fail-closed ones planTerminalStudy required. */
315
315
  export type LiveTerminalPlan = Extract<TerminalPlan, {
316
316
  readonly dryRun: false;
317
317
  }>;
318
- export type TerminalProductLabErrorCode = NonNullable<TerminalProductLabResult["error"]>["code"];
318
+ export type TerminalProductStudyErrorCode = NonNullable<TerminalProductStudyResult["error"]>["code"];
319
319
  /** The runtime key's command-scoped placement, built by a live run's checks of this machine. */
320
320
  export type LiveTerminalAuth = Extract<ReturnType<typeof buildRuntimeAuth>, {
321
321
  ok: true;
@@ -325,8 +325,8 @@ export interface RunLiveTerminalSessionArgs {
325
325
  input: TerminalRunInput;
326
326
  cwd: string;
327
327
  warnings: string[];
328
- failed: (code: TerminalProductLabErrorCode, message: string) => TerminalProductLabResult;
329
- /** The lab's run scope; the live session starts its run in it. */
328
+ failed: (code: TerminalProductStudyErrorCode, message: string) => TerminalProductStudyResult;
329
+ /** The study's run scope; the live session starts its run in it. */
330
330
  scope: RunScope;
331
331
  runtimeEnv: LiveTerminalAuth;
332
332
  }
@@ -1,8 +1,8 @@
1
1
  import {} from "../../analysis/automatic-completion.js";
2
2
  import {} from "../../run/bundle.js";
3
3
  import {} from "../../run/study-result.js";
4
- /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
5
- export const TERMINAL_PRODUCT_LAB_PROVIDER_METADATA = {
4
+ /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_STUDY_PROVIDER_METADATA). */
5
+ export const TERMINAL_PRODUCT_STUDY_PROVIDER_METADATA = {
6
6
  mode: "terminal-product-lab",
7
7
  tool: "humanish",
8
8
  };
@@ -89,7 +89,7 @@ export interface RunAdapterArtifact {
89
89
  * Provenance for a config-declared adopter scorer: the repo-relative entry path and a digest
90
90
  * of its entry-module bytes, recorded so a `review.scorer.ref`/`--scorer` run states which
91
91
  * out-of-tree judgment it attached. Core-computed (path + digest), never adopter-supplied. A library
92
- * caller (hooks passed directly through RunLabOptions) has implicit provenance, because its code is its
92
+ * caller (hooks passed directly through RunStudyOptions) has implicit provenance, because its code is its
93
93
  * provenance, so this block is absent there and every older bundle stays byte-stable + verifiable.
94
94
  *
95
95
  * The digest pins the entry file's identity only; modules it loads are outside it: a `export { score } from
@@ -135,7 +135,7 @@ export interface RunEvent {
135
135
  * One executed (or declared) subject-state seed step. Live records carry execution fields
136
136
  * (ok/exitCode/timedOut/durationMs); dry-run "declared, not run" records carry only the
137
137
  * declaration (name, phase, command digest). The command itself never persists; the digest
138
- * pins "same recipe" across bundles while the lab YAML in the consumer's repo stays the
138
+ * pins "same recipe" across bundles while the study YAML in the consumer's repo stays the
139
139
  * plaintext source of truth (publish-safe by construction).
140
140
  */
141
141
  export interface RunSubjectStateStepRecord {
@@ -336,7 +336,7 @@ export interface RunBundle {
336
336
  * `lab` and the source convention of older bundles, through studyProvenanceOf.
337
337
  */
338
338
  study?: RunStudyProvenance;
339
- /** `study`'s value, written beside it until 0.109. */
339
+ /** `study`'s value, as runs saved by 0.108 and earlier wrote it. humanish no longer writes it. */
340
340
  lab?: RunStudyProvenance;
341
341
  /**
342
342
  * Optional, additive run-level cost estimate (humanish.run-cost-summary.v1): the sum of every
@@ -489,7 +489,7 @@ export interface ReviewSummary {
489
489
  */
490
490
  participants?: ParticipantOutcomes;
491
491
  /**
492
- * The study's per-task completion rates, present only when the lab declared a protocol
492
+ * The study's per-task completion rates, present only when the study declared a protocol
493
493
  * and at least one session produced a funnel. Absent means no protocol was measured, never that
494
494
  * everyone finished.
495
495
  */
@@ -527,11 +527,11 @@ export interface BundleRun {
527
527
  readonly mode: RunBundle["mode"];
528
528
  readonly createdAt: string;
529
529
  /** The manifest the run came from, as the plan carried it to startRun. */
530
- readonly lab?: RunStudyProvenance | undefined;
530
+ readonly study?: RunStudyProvenance | undefined;
531
531
  }
532
532
  /**
533
533
  * The fields every run bundle starts with, in the saved order. The run supplies its id, mode,
534
- * start time and lab; the route passes the participant count and source. The public target cwd
534
+ * start time and study; the route passes the participant count and source. The public target cwd
535
535
  * and the run's own artifact root are the defaults.
536
536
  */
537
537
  export declare function bundleHead(run: BundleRun, args: {
@@ -541,7 +541,7 @@ export declare function bundleHead(run: BundleRun, args: {
541
541
  cwd?: string;
542
542
  artifactRoot?: string;
543
543
  source: RunBundle["source"];
544
- }): Pick<RunBundle, "schema" | "publication" | "runId" | "mode" | "simCount" | "createdAt" | "cwd" | "artifactRoot" | "study" | "lab" | "source">;
544
+ }): Pick<RunBundle, "schema" | "publication" | "runId" | "mode" | "simCount" | "createdAt" | "cwd" | "artifactRoot" | "study" | "source">;
545
545
  /** The files every run directory holds, as the bundle names them. */
546
546
  export declare function bundleArtifacts(): RunBundle["artifacts"];
547
547
  export declare function buildRunSource(args: {
@@ -8,7 +8,7 @@ export const REVIEW_SCHEMA = "humanish.review.v1";
8
8
  export const PUBLIC_TARGET_CWD = "[target-cwd]";
9
9
  /**
10
10
  * The fields every run bundle starts with, in the saved order. The run supplies its id, mode,
11
- * start time and lab; the route passes the participant count and source. The public target cwd
11
+ * start time and study; the route passes the participant count and source. The public target cwd
12
12
  * and the run's own artifact root are the defaults.
13
13
  */
14
14
  export function bundleHead(run, args) {
@@ -21,7 +21,7 @@ export function bundleHead(run, args) {
21
21
  createdAt: run.createdAt,
22
22
  cwd: args.cwd ?? PUBLIC_TARGET_CWD,
23
23
  artifactRoot: args.artifactRoot ?? path.join(".humanish", "runs", run.runId),
24
- ...studyFields(run.lab),
24
+ ...studyFields(run.study),
25
25
  source: args.source,
26
26
  };
27
27
  }