humanish 0.106.1 → 0.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (668) hide show
  1. package/ARCHITECTURE.md +38 -32
  2. package/CHANGELOG.md +28 -0
  3. package/CONTEXT.md +51 -41
  4. package/README.md +152 -174
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-client.js +2 -1
  14. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  15. package/dist/actors/codex/app-server-trace.js +1 -3
  16. package/dist/actors/codex/app-server-ui.js +1 -1
  17. package/dist/actors/codex/app-server.js +2 -1
  18. package/dist/actors/codex/codex-admission.d.ts +91 -0
  19. package/dist/actors/codex/codex-admission.js +150 -0
  20. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  21. package/dist/actors/codex/protocol-compat.js +357 -0
  22. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  23. package/dist/actors/codex/protocol-contract.js +471 -0
  24. package/dist/actors/codex/restricted-executable.d.ts +28 -4
  25. package/dist/actors/codex/restricted-executable.js +104 -29
  26. package/dist/actors/codex/restricted-launch.d.ts +9 -2
  27. package/dist/actors/codex/restricted-launch.js +43 -4
  28. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  29. package/dist/actors/codex/restricted-notifications.js +277 -0
  30. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  31. package/dist/actors/codex/restricted-participant.js +66 -6
  32. package/dist/actors/codex/restricted-policy.d.ts +11 -3
  33. package/dist/actors/codex/restricted-policy.js +2 -2
  34. package/dist/actors/codex/restricted-session.d.ts +16 -3
  35. package/dist/actors/codex/restricted-session.js +60 -22
  36. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  37. package/dist/actors/codex/restricted-transport.js +139 -27
  38. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  39. package/dist/actors/codex/restricted-turn.js +43 -30
  40. package/dist/actors/computer-use/actor.d.ts +17 -17
  41. package/dist/actors/computer-use/actor.js +6 -6
  42. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  43. package/dist/actors/computer-use/admission-limit.js +1 -1
  44. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  45. package/dist/actors/computer-use/loop/actions.js +10 -10
  46. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  47. package/dist/actors/computer-use/loop/backstop.js +15 -13
  48. package/dist/actors/computer-use/loop/ending.d.ts +7 -7
  49. package/dist/actors/computer-use/loop/ending.js +9 -9
  50. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  51. package/dist/actors/computer-use/loop/observation.js +9 -9
  52. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  53. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  54. package/dist/actors/computer-use/loop/session.js +3 -3
  55. package/dist/actors/computer-use/loop/spend.d.ts +2 -2
  56. package/dist/actors/computer-use/loop/spend.js +4 -4
  57. package/dist/actors/computer-use/loop/trace.js +11 -10
  58. package/dist/actors/computer-use/loop/types.d.ts +37 -26
  59. package/dist/actors/computer-use/loop/usage.js +2 -2
  60. package/dist/actors/computer-use/loop.js +4 -4
  61. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  62. package/dist/actors/computer-use/openai-context.js +214 -0
  63. package/dist/actors/computer-use/openai-provider.d.ts +12 -9
  64. package/dist/actors/computer-use/openai-provider.js +47 -36
  65. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  66. package/dist/actors/computer-use/openai-requests.js +82 -15
  67. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  68. package/dist/actors/computer-use/openai-wire.js +36 -34
  69. package/dist/actors/contract.d.ts +86 -49
  70. package/dist/actors/contract.js +29 -23
  71. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  72. package/dist/actors/local-agent/claude-session.js +10 -9
  73. package/dist/actors/local-agent/cli.d.ts +8 -6
  74. package/dist/actors/local-agent/cli.js +24 -28
  75. package/dist/actors/local-agent/readiness.d.ts +2 -2
  76. package/dist/actors/local-agent/readiness.js +4 -4
  77. package/dist/actors/reasoning-effort.js +6 -6
  78. package/dist/actors/registry.d.ts +10 -10
  79. package/dist/actors/registry.js +18 -17
  80. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  81. package/dist/actors/scripted-browser/actor.js +16 -16
  82. package/dist/actors/scripted-browser/browser-command.js +1 -1
  83. package/dist/actors/scripted-browser/journey.js +15 -4
  84. package/dist/actors/scripted-browser/steps.js +19 -1
  85. package/dist/actors/scripted-browser/types.d.ts +12 -2
  86. package/dist/actors/stop-conditions.d.ts +1 -1
  87. package/dist/actors/stop-conditions.js +1 -3
  88. package/dist/analysis/automatic-completion.d.ts +13 -8
  89. package/dist/analysis/automatic-completion.js +14 -8
  90. package/dist/analysis/automatic-config.d.ts +1 -1
  91. package/dist/analysis/automatic-config.js +2 -2
  92. package/dist/analysis/automatic.d.ts +10 -4
  93. package/dist/analysis/automatic.js +17 -13
  94. package/dist/analysis/codex-config.d.ts +6 -2
  95. package/dist/analysis/codex-config.js +22 -14
  96. package/dist/analysis/diagnostics.d.ts +23 -0
  97. package/dist/analysis/diagnostics.js +112 -0
  98. package/dist/analysis/evidence-sources.js +2 -2
  99. package/dist/analysis/evidence.js +6 -6
  100. package/dist/analysis/execute.d.ts +7 -1
  101. package/dist/analysis/execute.js +39 -12
  102. package/dist/analysis/job.d.ts +8 -5
  103. package/dist/analysis/job.js +15 -14
  104. package/dist/analysis/load.d.ts +1 -1
  105. package/dist/analysis/load.js +5 -5
  106. package/dist/analysis/provider.d.ts +9 -1
  107. package/dist/analysis/restricted-codex.d.ts +2 -0
  108. package/dist/analysis/restricted-codex.js +10 -1
  109. package/dist/analysis/service.d.ts +2 -0
  110. package/dist/analysis/service.js +35 -16
  111. package/dist/analysis/sharing.d.ts +2 -2
  112. package/dist/analysis/sharing.js +5 -5
  113. package/dist/analysis/store-executions.d.ts +5 -5
  114. package/dist/analysis/store-executions.js +12 -12
  115. package/dist/analysis/store.d.ts +4 -4
  116. package/dist/analysis/store.js +13 -13
  117. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  118. package/dist/cli/commands/analysis-signals.js +4 -1
  119. package/dist/cli/commands/analyze.js +23 -18
  120. package/dist/cli/commands/codex.js +9 -9
  121. package/dist/cli/commands/comms.js +62 -34
  122. package/dist/cli/commands/feedback.js +20 -21
  123. package/dist/cli/commands/lab-format.d.ts +5 -4
  124. package/dist/cli/commands/lab-format.js +35 -23
  125. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  126. package/dist/cli/commands/lab-route-computer-use.js +32 -21
  127. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  128. package/dist/cli/commands/lab-route-preview.js +7 -7
  129. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  130. package/dist/cli/commands/lab-route-run.js +6 -2
  131. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  132. package/dist/cli/commands/lab-route-scripted.js +0 -1
  133. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  134. package/dist/cli/commands/lab-route-shared-world.js +3 -4
  135. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  136. package/dist/cli/commands/lab-route-terminal.js +0 -1
  137. package/dist/cli/commands/lab-run.js +84 -54
  138. package/dist/cli/commands/lab-scorer.d.ts +2 -4
  139. package/dist/cli/commands/lab-scorer.js +1 -1
  140. package/dist/cli/commands/migrate.d.ts +4 -0
  141. package/dist/cli/commands/migrate.js +65 -0
  142. package/dist/cli/commands/observe.js +168 -107
  143. package/dist/cli/commands/run-command.d.ts +10 -0
  144. package/dist/cli/commands/run-command.js +85 -0
  145. package/dist/cli/commands/run-signals.d.ts +30 -0
  146. package/dist/cli/commands/run-signals.js +146 -0
  147. package/dist/cli/commands/runs.js +137 -136
  148. package/dist/cli/commands/setup.d.ts +2 -2
  149. package/dist/cli/commands/setup.js +26 -21
  150. package/dist/cli/commands/study.d.ts +3 -0
  151. package/dist/cli/commands/study.js +182 -0
  152. package/dist/cli/commands/tui.d.ts +4 -4
  153. package/dist/cli/commands/tui.js +21 -21
  154. package/dist/cli/commands/watch.js +64 -77
  155. package/dist/cli/deprecations.d.ts +18 -0
  156. package/dist/cli/deprecations.js +48 -0
  157. package/dist/cli/doctor.d.ts +18 -5
  158. package/dist/cli/doctor.js +111 -48
  159. package/dist/cli/first-run-path.d.ts +12 -10
  160. package/dist/cli/first-run-path.js +30 -28
  161. package/dist/cli/io.d.ts +46 -10
  162. package/dist/cli/io.js +109 -30
  163. package/dist/cli/observer-follow.d.ts +2 -2
  164. package/dist/cli/observer-follow.js +5 -6
  165. package/dist/cli/orientation.d.ts +6 -3
  166. package/dist/cli/orientation.js +43 -39
  167. package/dist/cli/product-sentence.d.ts +6 -0
  168. package/dist/cli/product-sentence.js +6 -0
  169. package/dist/cli/program.d.ts +6 -1
  170. package/dist/cli/program.js +112 -43
  171. package/dist/cli/telemetry.d.ts +17 -17
  172. package/dist/cli/telemetry.js +49 -41
  173. package/dist/cli.js +1 -1
  174. package/dist/comms/capture-surface.d.ts +14 -13
  175. package/dist/comms/capture-surface.js +23 -22
  176. package/dist/comms/catch-host.d.ts +8 -8
  177. package/dist/comms/catch-host.js +14 -14
  178. package/dist/comms/connections.js +4 -4
  179. package/dist/comms/email-catch.d.ts +3 -3
  180. package/dist/comms/email-catch.js +8 -8
  181. package/dist/comms/external-evidence.d.ts +27 -0
  182. package/dist/comms/external-evidence.js +93 -0
  183. package/dist/comms/extract.js +2 -2
  184. package/dist/comms/fake-inbox.d.ts +2 -2
  185. package/dist/comms/fake-inbox.js +2 -2
  186. package/dist/comms/lease-store.js +7 -7
  187. package/dist/comms/receiving-render.d.ts +1 -1
  188. package/dist/comms/receiving-render.js +2 -2
  189. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  190. package/dist/comms/sandbox-catch-script.js +6 -6
  191. package/dist/comms/sandbox-catch.d.ts +36 -37
  192. package/dist/comms/sandbox-catch.js +34 -35
  193. package/dist/comms/setup.js +42 -8
  194. package/dist/comms/thread-evidence.d.ts +1 -1
  195. package/dist/comms/thread-evidence.js +6 -6
  196. package/dist/comms/types.d.ts +6 -6
  197. package/dist/comms/types.js +4 -4
  198. package/dist/evidence/browser-hygiene.d.ts +1 -1
  199. package/dist/evidence/browser-hygiene.js +1 -1
  200. package/dist/evidence/frame-signature.d.ts +1 -1
  201. package/dist/evidence/frame-signature.js +4 -4
  202. package/dist/evidence/redaction.d.ts +3 -3
  203. package/dist/evidence/redaction.js +5 -5
  204. package/dist/evidence/secret-scrub.d.ts +9 -0
  205. package/dist/evidence/secret-scrub.js +96 -0
  206. package/dist/feedback/draft.js +41 -85
  207. package/dist/feedback/export-bundle.js +5 -5
  208. package/dist/feedback/export.d.ts +5 -1
  209. package/dist/feedback/export.js +16 -17
  210. package/dist/feedback/feedback.d.ts +3 -3
  211. package/dist/feedback/feedback.js +21 -3
  212. package/dist/guest/chromium-text.js +2 -2
  213. package/dist/guest/desktop-native.d.ts +1 -1
  214. package/dist/guest/runtime.js +1 -1
  215. package/dist/index.d.ts +14 -15
  216. package/dist/index.js +10 -11
  217. package/dist/keys/key-resolution.d.ts +7 -5
  218. package/dist/keys/key-resolution.js +40 -38
  219. package/dist/lab/adapter-extension.d.ts +35 -13
  220. package/dist/lab/adapter-extension.js +50 -134
  221. package/dist/lab/adapter-scorer-loader.d.ts +32 -12
  222. package/dist/lab/adapter-scorer-loader.js +56 -32
  223. package/dist/lab/composition-rules.js +58 -58
  224. package/dist/lab/config.js +85 -43
  225. package/dist/lab/deprecated-fields.d.ts +10 -0
  226. package/dist/lab/deprecated-fields.js +24 -0
  227. package/dist/lab/device-presets.d.ts +10 -10
  228. package/dist/lab/device-presets.js +11 -11
  229. package/dist/lab/discover.d.ts +13 -9
  230. package/dist/lab/discover.js +118 -60
  231. package/dist/lab/doctor.d.ts +53 -11
  232. package/dist/lab/doctor.js +193 -47
  233. package/dist/lab/init-plan.js +1 -3
  234. package/dist/lab/init-templates.js +147 -147
  235. package/dist/lab/init.d.ts +1 -1
  236. package/dist/lab/init.js +41 -9
  237. package/dist/lab/keys.d.ts +2 -0
  238. package/dist/lab/keys.js +43 -9
  239. package/dist/lab/lab-deps.d.ts +80 -0
  240. package/dist/lab/lab-deps.js +4 -0
  241. package/dist/lab/parse/actors.js +17 -16
  242. package/dist/lab/parse/comms.js +8 -7
  243. package/dist/lab/parse/execution.js +15 -14
  244. package/dist/lab/parse/study-v3.d.ts +23 -0
  245. package/dist/lab/parse/study-v3.js +259 -0
  246. package/dist/lab/parse/subject-state.d.ts +7 -7
  247. package/dist/lab/parse/subject-state.js +18 -17
  248. package/dist/lab/parse/subject.js +30 -29
  249. package/dist/lab/parse/values.d.ts +1 -2
  250. package/dist/lab/parse/values.js +3 -6
  251. package/dist/lab/persona-resolve.d.ts +7 -7
  252. package/dist/lab/persona-resolve.js +8 -8
  253. package/dist/lab/persona.js +1 -3
  254. package/dist/lab/plan-base.d.ts +0 -2
  255. package/dist/lab/plan-base.js +6 -4
  256. package/dist/lab/plan-participants.d.ts +7 -7
  257. package/dist/lab/plan-participants.js +2 -2
  258. package/dist/lab/plan-types.d.ts +26 -8
  259. package/dist/lab/plan.d.ts +4 -18
  260. package/dist/lab/plan.js +24 -79
  261. package/dist/lab/preflight-probes.js +11 -11
  262. package/dist/lab/preflight-result.d.ts +2 -1
  263. package/dist/lab/preflight-result.js +5 -6
  264. package/dist/lab/preflight.d.ts +7 -8
  265. package/dist/lab/preflight.js +6 -6
  266. package/dist/lab/requirements.d.ts +20 -0
  267. package/dist/lab/requirements.js +54 -0
  268. package/dist/lab/route-inputs.d.ts +23 -12
  269. package/dist/lab/route-inputs.js +48 -51
  270. package/dist/lab/routing.d.ts +42 -41
  271. package/dist/lab/routing.js +66 -68
  272. package/dist/lab/run-lab-events.d.ts +3 -11
  273. package/dist/lab/run-lab-events.js +2 -16
  274. package/dist/lab/run-lab-homes.d.ts +76 -0
  275. package/dist/lab/run-lab-homes.js +7 -0
  276. package/dist/lab/run-lab-options.d.ts +12 -66
  277. package/dist/lab/run-lab-options.js +58 -285
  278. package/dist/lab/summary.d.ts +15 -9
  279. package/dist/lab/summary.js +24 -17
  280. package/dist/lab/tasks.d.ts +15 -15
  281. package/dist/lab/tasks.js +14 -14
  282. package/dist/lab/types.d.ts +201 -195
  283. package/dist/lab/types.js +2 -0
  284. package/dist/lab/validation.d.ts +21 -21
  285. package/dist/lab/validation.js +61 -59
  286. package/dist/lab/warnings.d.ts +10 -0
  287. package/dist/lab/warnings.js +70 -41
  288. package/dist/library-aliases.d.ts +56 -0
  289. package/dist/library-aliases.js +22 -0
  290. package/dist/observer/artifact.d.ts +2 -2
  291. package/dist/observer/artifact.js +9 -9
  292. package/dist/observer/data.d.ts +6 -6
  293. package/dist/observer/data.js +7 -6
  294. package/dist/observer/exposure.d.ts +1 -1
  295. package/dist/observer/exposure.js +11 -11
  296. package/dist/observer/http.js +1 -1
  297. package/dist/observer/library.d.ts +1 -1
  298. package/dist/observer/library.js +4 -2
  299. package/dist/observer/listen.js +5 -4
  300. package/dist/observer/render.d.ts +1 -1
  301. package/dist/observer/render.js +12 -7
  302. package/dist/observer/run-routes.d.ts +4 -4
  303. package/dist/observer/run-routes.js +6 -6
  304. package/dist/observer/serve.d.ts +17 -0
  305. package/dist/observer/serve.js +41 -6
  306. package/dist/observer/tunnel.js +1 -1
  307. package/dist/observer-app.html +4 -4
  308. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  309. package/dist/routes/computer-use/bundle-parts.js +24 -17
  310. package/dist/routes/computer-use/bundle.d.ts +4 -11
  311. package/dist/routes/computer-use/bundle.js +12 -18
  312. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  313. package/dist/routes/computer-use/diagnostics.js +1 -1
  314. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +11 -11
  315. package/dist/routes/computer-use/e2b-desktop/comms.js +24 -27
  316. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  317. package/dist/routes/computer-use/e2b-desktop/desktop.js +8 -11
  318. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +16 -15
  319. package/dist/routes/computer-use/e2b-desktop/fidelity.js +20 -19
  320. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  321. package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -43
  322. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  323. package/dist/routes/computer-use/e2b-desktop/start.js +32 -30
  324. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  325. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  326. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  327. package/dist/routes/computer-use/e2b-desktop/teardown.js +33 -20
  328. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  329. package/dist/routes/computer-use/external-comms.js +19 -43
  330. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  331. package/dist/routes/computer-use/fanout-bundle.js +38 -42
  332. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +33 -28
  333. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  334. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  335. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  336. package/dist/routes/computer-use/live-flush.js +20 -28
  337. package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +4 -2
  338. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +17 -16
  339. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  340. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  341. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  342. package/dist/routes/computer-use/local-vm.js +40 -67
  343. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  344. package/dist/routes/computer-use/participant-desktop.js +5 -25
  345. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +11 -11
  346. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +39 -26
  347. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  348. package/dist/routes/computer-use/participant-facts.js +12 -1
  349. package/dist/routes/computer-use/participant-model.d.ts +25 -11
  350. package/dist/routes/computer-use/participant-model.js +76 -34
  351. package/dist/routes/computer-use/participant-prompt.d.ts +13 -13
  352. package/dist/routes/computer-use/participant-prompt.js +8 -8
  353. package/dist/routes/computer-use/participant-runs.d.ts +11 -11
  354. package/dist/routes/computer-use/participant-runs.js +18 -18
  355. package/dist/routes/computer-use/plan.d.ts +21 -29
  356. package/dist/routes/computer-use/plan.js +70 -78
  357. package/dist/routes/computer-use/preflight.d.ts +3 -5
  358. package/dist/routes/computer-use/preflight.js +40 -36
  359. package/dist/routes/computer-use/rerun-selection.js +11 -7
  360. package/dist/routes/computer-use/result.d.ts +1 -1
  361. package/dist/routes/computer-use/result.js +48 -38
  362. package/dist/routes/computer-use/route.d.ts +5 -5
  363. package/dist/routes/computer-use/route.js +36 -33
  364. package/dist/routes/computer-use/self-report.d.ts +8 -8
  365. package/dist/routes/computer-use/self-report.js +33 -33
  366. package/dist/routes/computer-use/setup.d.ts +9 -15
  367. package/dist/routes/computer-use/setup.js +106 -83
  368. package/dist/routes/computer-use/single-bundle.d.ts +13 -16
  369. package/dist/routes/computer-use/single-bundle.js +46 -53
  370. package/dist/routes/computer-use/subject-projection.d.ts +6 -8
  371. package/dist/routes/computer-use/subject-projection.js +24 -23
  372. package/dist/routes/computer-use/types.d.ts +195 -238
  373. package/dist/routes/computer-use/types.js +21 -13
  374. package/dist/routes/preview.d.ts +8 -2
  375. package/dist/routes/preview.js +8 -5
  376. package/dist/routes/scripted/bundle.d.ts +5 -8
  377. package/dist/routes/scripted/bundle.js +23 -27
  378. package/dist/routes/scripted/plan.d.ts +6 -8
  379. package/dist/routes/scripted/plan.js +15 -13
  380. package/dist/routes/scripted/result.d.ts +4 -1
  381. package/dist/routes/scripted/result.js +15 -11
  382. package/dist/routes/scripted/route.js +15 -17
  383. package/dist/routes/scripted/scenario.d.ts +1 -1
  384. package/dist/routes/scripted/scenario.js +3 -3
  385. package/dist/routes/scripted/setup.d.ts +3 -2
  386. package/dist/routes/scripted/setup.js +27 -26
  387. package/dist/routes/scripted/subject.d.ts +8 -3
  388. package/dist/routes/scripted/subject.js +10 -6
  389. package/dist/routes/scripted/surface-records.js +4 -4
  390. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  391. package/dist/routes/scripted/surface-sessions.js +4 -4
  392. package/dist/routes/scripted/types.d.ts +21 -40
  393. package/dist/routes/scripted/types.js +2 -3
  394. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +17 -16
  395. package/dist/routes/shared-world/bundle.d.ts +7 -7
  396. package/dist/routes/shared-world/bundle.js +60 -62
  397. package/dist/routes/shared-world/checkpoints.d.ts +5 -5
  398. package/dist/routes/shared-world/checkpoints.js +5 -5
  399. package/dist/routes/shared-world/comms.d.ts +8 -7
  400. package/dist/routes/shared-world/comms.js +38 -51
  401. package/dist/routes/shared-world/external-public.d.ts +6 -5
  402. package/dist/routes/shared-world/external-public.js +28 -25
  403. package/dist/routes/shared-world/handoff.d.ts +10 -9
  404. package/dist/routes/shared-world/handoff.js +89 -81
  405. package/dist/routes/shared-world/lobby-code.d.ts +7 -7
  406. package/dist/routes/shared-world/lobby-code.js +22 -22
  407. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +15 -12
  408. package/dist/routes/shared-world/{seats.js → participant-specs.js} +65 -63
  409. package/dist/routes/shared-world/plan.d.ts +2 -6
  410. package/dist/routes/shared-world/plan.js +8 -9
  411. package/dist/routes/shared-world/provenance.d.ts +4 -4
  412. package/dist/routes/shared-world/provenance.js +4 -4
  413. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  414. package/dist/routes/shared-world/provisioned.js +55 -48
  415. package/dist/routes/shared-world/result.js +47 -36
  416. package/dist/routes/shared-world/route.js +54 -57
  417. package/dist/routes/shared-world/setup.d.ts +6 -5
  418. package/dist/routes/shared-world/setup.js +16 -18
  419. package/dist/routes/shared-world/types.d.ts +70 -141
  420. package/dist/routes/shared-world/types.js +5 -5
  421. package/dist/routes/terminal/adapter.d.ts +10 -10
  422. package/dist/routes/terminal/adapter.js +32 -129
  423. package/dist/routes/terminal/bundle.d.ts +10 -15
  424. package/dist/routes/terminal/bundle.js +43 -52
  425. package/dist/routes/terminal/credentials.d.ts +4 -4
  426. package/dist/routes/terminal/credentials.js +20 -20
  427. package/dist/routes/terminal/dry-run.d.ts +1 -1
  428. package/dist/routes/terminal/dry-run.js +13 -15
  429. package/dist/routes/terminal/encoding.d.ts +1 -1
  430. package/dist/routes/terminal/encoding.js +4 -4
  431. package/dist/routes/terminal/ledger.d.ts +8 -8
  432. package/dist/routes/terminal/ledger.js +22 -22
  433. package/dist/routes/terminal/live-finish.d.ts +1 -2
  434. package/dist/routes/terminal/live-finish.js +24 -23
  435. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  436. package/dist/routes/terminal/live-sandbox.js +31 -32
  437. package/dist/routes/terminal/participant-text.d.ts +23 -0
  438. package/dist/routes/terminal/participant-text.js +165 -0
  439. package/dist/routes/terminal/persona.js +1 -1
  440. package/dist/routes/terminal/plan.d.ts +2 -6
  441. package/dist/routes/terminal/plan.js +23 -19
  442. package/dist/routes/terminal/recorder.d.ts +6 -1
  443. package/dist/routes/terminal/recorder.js +12 -4
  444. package/dist/routes/terminal/result.js +12 -12
  445. package/dist/routes/terminal/route.js +30 -31
  446. package/dist/routes/terminal/runtime.d.ts +3 -2
  447. package/dist/routes/terminal/runtime.js +3 -3
  448. package/dist/routes/terminal/sandbox.d.ts +4 -4
  449. package/dist/routes/terminal/sandbox.js +10 -10
  450. package/dist/routes/terminal/session.js +22 -19
  451. package/dist/routes/terminal/token-usage.d.ts +1 -1
  452. package/dist/routes/terminal/token-usage.js +10 -11
  453. package/dist/routes/terminal/trace.d.ts +7 -10
  454. package/dist/routes/terminal/trace.js +11 -66
  455. package/dist/routes/terminal/types.d.ts +104 -114
  456. package/dist/routes/terminal/types.js +12 -7
  457. package/dist/run/active-runs.d.ts +13 -0
  458. package/dist/run/active-runs.js +12 -0
  459. package/dist/run/bundle-shape.d.ts +2 -1
  460. package/dist/run/bundle-shape.js +7 -7
  461. package/dist/run/bundle.d.ts +99 -92
  462. package/dist/run/bundle.js +10 -8
  463. package/dist/run/cost-summary.js +6 -5
  464. package/dist/run/costs.d.ts +6 -6
  465. package/dist/run/costs.js +17 -11
  466. package/dist/run/detail.d.ts +9 -9
  467. package/dist/run/detail.js +10 -10
  468. package/dist/run/dry-run-inputs.js +1 -1
  469. package/dist/run/dry-run.js +23 -30
  470. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  471. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  472. package/dist/run/feedback-shape.js +1 -1
  473. package/dist/run/judge.d.ts +34 -16
  474. package/dist/run/judge.js +41 -14
  475. package/dist/run/locate.d.ts +2 -0
  476. package/dist/run/locate.js +3 -1
  477. package/dist/run/outcomes.d.ts +3 -3
  478. package/dist/run/outcomes.js +3 -3
  479. package/dist/run/participant-records.d.ts +2 -2
  480. package/dist/run/participant-records.js +2 -2
  481. package/dist/run/paths.d.ts +1 -1
  482. package/dist/run/paths.js +2 -2
  483. package/dist/run/pricing.d.ts +30 -15
  484. package/dist/run/pricing.js +49 -30
  485. package/dist/run/projection.d.ts +27 -27
  486. package/dist/run/projection.js +23 -23
  487. package/dist/run/reclaim.d.ts +6 -0
  488. package/dist/run/reclaim.js +15 -5
  489. package/dist/run/results.d.ts +5 -5
  490. package/dist/run/run-index.d.ts +9 -7
  491. package/dist/run/run-index.js +24 -25
  492. package/dist/run/run-not-found.d.ts +5 -0
  493. package/dist/run/run-not-found.js +15 -0
  494. package/dist/run/run.d.ts +7 -4
  495. package/dist/run/run.js +10 -6
  496. package/dist/run/sandbox-receipts.d.ts +5 -5
  497. package/dist/run/sandbox-receipts.js +6 -6
  498. package/dist/run/shared-world-evidence.d.ts +67 -66
  499. package/dist/run/shared-world-evidence.js +4 -4
  500. package/dist/run/shared-world-shape.d.ts +3 -3
  501. package/dist/run/shared-world-shape.js +16 -16
  502. package/dist/run/stats.d.ts +17 -11
  503. package/dist/run/stats.js +124 -66
  504. package/dist/run/status.d.ts +21 -32
  505. package/dist/run/status.js +34 -33
  506. package/dist/run/stored-runs.js +2 -1
  507. package/dist/run/stream-shape.js +1 -1
  508. package/dist/run/streams.d.ts +29 -22
  509. package/dist/run/study-provenance.d.ts +47 -0
  510. package/dist/run/study-provenance.js +63 -0
  511. package/dist/run/study-result.d.ts +16 -0
  512. package/dist/run/study-result.js +9 -0
  513. package/dist/run/terminal-contract.d.ts +5 -5
  514. package/dist/run/terminal-contract.js +4 -4
  515. package/dist/run/text.d.ts +2 -0
  516. package/dist/run/text.js +4 -0
  517. package/dist/run/transient-comms-secrets.d.ts +5 -0
  518. package/dist/run/transient-comms-secrets.js +12 -0
  519. package/dist/run-lab.d.ts +40 -38
  520. package/dist/run-lab.js +42 -40
  521. package/dist/study/convert.d.ts +33 -0
  522. package/dist/study/convert.js +432 -0
  523. package/dist/study/field-paths.d.ts +12 -0
  524. package/dist/study/field-paths.js +126 -0
  525. package/dist/study/files.d.ts +26 -0
  526. package/dist/study/files.js +43 -0
  527. package/dist/study/migrate.d.ts +48 -0
  528. package/dist/study/migrate.js +408 -0
  529. package/dist/study/owned-files.d.ts +38 -0
  530. package/dist/study/owned-files.js +182 -0
  531. package/dist/subject/clone.d.ts +1 -1
  532. package/dist/subject/desktop-cli.d.ts +2 -2
  533. package/dist/subject/desktop-cli.js +3 -3
  534. package/dist/subject/local-tree-archive.d.ts +1 -1
  535. package/dist/subject/local-tree-archive.js +5 -5
  536. package/dist/subject/local-tree.d.ts +3 -3
  537. package/dist/subject/local-tree.js +1 -1
  538. package/dist/subject/node-bootstrap.d.ts +1 -1
  539. package/dist/subject/node-bootstrap.js +4 -4
  540. package/dist/subject/runtime.js +10 -11
  541. package/dist/subject/serve.d.ts +1 -1
  542. package/dist/subject/serve.js +4 -4
  543. package/dist/subject/state.d.ts +1 -1
  544. package/dist/subject/steps.d.ts +8 -8
  545. package/dist/subject/steps.js +7 -7
  546. package/dist/substrates/command-failure.d.ts +3 -3
  547. package/dist/substrates/command-failure.js +3 -3
  548. package/dist/substrates/detached.d.ts +6 -6
  549. package/dist/substrates/detached.js +7 -7
  550. package/dist/substrates/e2b/cdp-probe.d.ts +11 -11
  551. package/dist/substrates/e2b/cdp-probe.js +15 -18
  552. package/dist/substrates/e2b/desktop-browser.d.ts +5 -5
  553. package/dist/substrates/e2b/desktop-browser.js +12 -12
  554. package/dist/substrates/e2b/desktop-cdp.d.ts +15 -15
  555. package/dist/substrates/e2b/desktop-cdp.js +11 -11
  556. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  557. package/dist/substrates/e2b/desktop-executor.js +1 -1
  558. package/dist/substrates/e2b/desktop-geometry.d.ts +6 -6
  559. package/dist/substrates/e2b/desktop-geometry.js +9 -9
  560. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  561. package/dist/substrates/e2b/desktop-media.js +3 -3
  562. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  563. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  564. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  565. package/dist/substrates/e2b/sandbox.js +2 -2
  566. package/dist/substrates/e2b/sdk.d.ts +11 -11
  567. package/dist/substrates/e2b/sdk.js +8 -8
  568. package/dist/substrates/local/runtime-host.d.ts +2 -0
  569. package/dist/substrates/local/runtime-host.js +6 -0
  570. package/dist/tui/actions.d.ts +8 -6
  571. package/dist/tui/actions.js +31 -22
  572. package/dist/tui/contract.d.ts +16 -16
  573. package/dist/tui/contract.js +10 -10
  574. package/dist/tui/launch.d.ts +4 -4
  575. package/dist/tui/launch.js +18 -19
  576. package/dist/tui/project.js +5 -5
  577. package/dist/tui-app.js +83 -83
  578. package/dist/verify/actor.d.ts +14 -14
  579. package/dist/verify/actor.js +45 -45
  580. package/dist/verify/artifacts.d.ts +3 -3
  581. package/dist/verify/artifacts.js +6 -6
  582. package/dist/verify/context-growth.d.ts +9 -0
  583. package/dist/verify/context-growth.js +62 -0
  584. package/dist/verify/costs.d.ts +7 -7
  585. package/dist/verify/costs.js +9 -9
  586. package/dist/verify/liveness.d.ts +1 -1
  587. package/dist/verify/liveness.js +4 -1
  588. package/dist/verify/rerun.d.ts +1 -1
  589. package/dist/verify/rerun.js +1 -1
  590. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  591. package/dist/verify/shared-world-concurrent.js +79 -76
  592. package/dist/verify/shared-world.d.ts +2 -2
  593. package/dist/verify/shared-world.js +18 -18
  594. package/dist/verify/subject.d.ts +4 -4
  595. package/dist/verify/subject.js +18 -18
  596. package/dist/verify/verify.js +98 -49
  597. package/docs/README.md +26 -33
  598. package/docs/architecture/actor-contract.md +105 -98
  599. package/docs/architecture/desktop-sessions.md +14 -14
  600. package/docs/architecture/external-public-shared-world.md +66 -59
  601. package/docs/architecture/github-feedback-loop.md +1 -4
  602. package/docs/architecture/guest-desktop.md +2 -2
  603. package/docs/architecture/observer.md +37 -37
  604. package/docs/architecture/restricted-codex-analysis.md +70 -30
  605. package/docs/architecture/serve.md +34 -37
  606. package/docs/architecture/state-driven-executor.md +55 -59
  607. package/docs/architecture/task-protocol-support.md +7 -9
  608. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +83 -115
  609. package/docs/contracts/README.md +24 -0
  610. package/docs/contracts/adapter-admission.md +3 -3
  611. package/docs/contracts/adapter-fixtures.md +2 -5
  612. package/docs/contracts/core.md +1 -3
  613. package/docs/contracts/errors.md +62 -0
  614. package/docs/contracts/feedback.md +8 -9
  615. package/docs/contracts/policy.md +7 -12
  616. package/docs/contracts/run-bundle.md +54 -51
  617. package/docs/contracts/schemas.md +505 -390
  618. package/docs/contracts/study-analysis.md +26 -2
  619. package/docs/contracts/study-costs.md +11 -7
  620. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  621. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  622. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  623. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  624. package/docs/principles/actor-fidelity.md +4 -4
  625. package/docs/principles/engineering.md +3 -3
  626. package/docs/principles/invariants-and-defaults.md +38 -38
  627. package/docs/principles/self-driving-harness.md +1 -5
  628. package/docs/principles/three-roles.md +1 -1
  629. package/docs/product/automatic-analysis.md +8 -7
  630. package/examples/participant/README.md +5 -5
  631. package/examples/participant/run.mjs +11 -10
  632. package/examples/scorer/README.md +3 -3
  633. package/examples/scorer/run.mjs +11 -12
  634. package/package.json +16 -17
  635. package/skills/humanish/SKILL.md +63 -60
  636. package/skills/humanish/agents/openai.yaml +1 -1
  637. package/AGENTS.md +0 -99
  638. package/CONTRIBUTING.md +0 -148
  639. package/dist/actors/codex/qualified-versions.d.ts +0 -45
  640. package/dist/actors/codex/qualified-versions.js +0 -87
  641. package/dist/cli/commands/lab.d.ts +0 -3
  642. package/dist/cli/commands/lab.js +0 -193
  643. package/dist/deprecated.d.ts +0 -90
  644. package/dist/deprecated.js +0 -106
  645. package/dist/lab/bag-overrides.d.ts +0 -18
  646. package/dist/lab/bag-overrides.js +0 -121
  647. package/dist/observer/static.d.ts +0 -39
  648. package/dist/observer/static.js +0 -369
  649. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  650. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  651. package/docs/architecture/comms-inbox.md +0 -122
  652. package/docs/architecture/desktop-recording.md +0 -80
  653. package/docs/architecture/local-browser-runtime.md +0 -178
  654. package/docs/architecture/observer-review.md +0 -144
  655. package/docs/architecture/participant-media.md +0 -90
  656. package/docs/architecture/project-layout.md +0 -62
  657. package/docs/architecture/real-email-receiving.md +0 -136
  658. package/docs/assets/humanish-drawdb-hero.png +0 -0
  659. package/docs/assets/humanish-observer-hero.png +0 -0
  660. package/docs/goals/current.md +0 -207
  661. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  662. package/docs/product/open-source-install-experience.md +0 -240
  663. package/docs/ramp/README.md +0 -294
  664. package/docs/release/open-source-readiness.md +0 -222
  665. package/docs/release/public-readiness-standard.md +0 -210
  666. package/docs/roadmap/world-class-open-source-v0.md +0 -311
  667. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  668. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -7,30 +7,38 @@ import {} from "../../substrates/e2b/sdk.js";
7
7
  import {} from "../../substrates/e2b/desktop-resources.js";
8
8
  import {} from "../../substrates/detached.js";
9
9
  import {} from "../../lab/types.js";
10
- import { renderObserver } from "../../observer/render.js";
11
- import {} from "../../run/status.js";
10
+ import {} from "../../observer/render.js";
12
11
  import {} from "../../run/bundle.js";
13
12
  import {} from "../../run/streams.js";
14
13
  import {} from "../../run/contained-output.js";
15
- import {} from "../../subject/local-tree-archive.js";
16
- export const CUA_ACTOR_LAB_SCHEMA = "humanish.cua-lab-result.v2";
17
- // The only fan-out topology this slice ships: N lanes = N independent E2B desktop sandboxes,
18
- // each its own world (clone/serve + subject.state per lane). Shared-world is layer 7 (#164).
14
+ import {} from "../../run/study-result.js";
15
+ // The fan-out topology of this route: N participants = N independent E2B desktop sandboxes,
16
+ // each its own world (clone/serve + subject.state per participant). Shared-world has its own route.
19
17
  export const CUA_FANOUT_STRATEGY = "per-lane-worlds";
20
- // Env override that may only LOWER the effective concurrency (never raise concurrent paid
21
- // desktops — invariant 3). Read names-only into a local; the value never persists.
18
+ // Env override that may only lower the effective concurrency (never raise concurrent paid
19
+ // desktops). Read names-only into a local; the value never persists.
22
20
  export const CUA_MAX_CONCURRENCY_ENV = "HUMANISH_CUA_MAX_CONCURRENCY";
23
- // The DEFAULT session budget, sized so a study can FINISH (docs/principles/three-roles.md: a
24
- // session ends because the participant is done, not because a timer fired — the time-box is a
21
+ // The default session budget, sized so a study can finish (docs/principles/three-roles.md: a
22
+ // session ends because the participant is done, not because a timer fired; the time-box is a
25
23
  // session-level cap a researcher sets generously; spend protection is the dollar caps' job).
26
24
  // The old 300s default ended real signup studies mid-flow: observed studies run 16-40 turns at
27
- // ~5-6s per turn BEFORE any email wait, so five minutes was the biggest single source of
25
+ // ~5-6s per turn before any email wait, so five minutes was the biggest single source of
28
26
  // budget_reached endings that read as participant failures.
29
27
  //
30
28
  // App-url and in-process routes default to 30 minutes. Provisioned routes (clone/local-tree)
31
29
  // default to whatever the 1-hour sandbox cap leaves after provisioning, declared state seeding,
32
- // and the teardown buffer — 20 minutes on a stateless clone — floored at the old five minutes so
33
- // a state-heavy lab still gets a session at all. An EXPLICIT execution.timeoutMs is never
30
+ // and the teardown buffer (20 minutes on a stateless clone), floored at the old five minutes so
31
+ // a state-heavy lab still gets a session at all. An explicit execution.timeoutMs is never
34
32
  // adjusted: when it cannot be provisioned, the plan-time cap refusal shows the arithmetic.
35
33
  export const DEFAULT_APP_URL_SESSION_TIMEOUT_MS = 30 * 60_000;
36
34
  export const MIN_DERIVED_SESSION_TIMEOUT_MS = 5 * 60_000;
35
+ /** The subject env names forwarded into a participant's sandbox: a provisioned subject's only. */
36
+ export function participantSubjectEnv(subject) {
37
+ return subject.kind === "clone" || subject.kind === "local-tree" ? subject.env : [];
38
+ }
39
+ /** The serve URL a participant's inbox maps links back to: the served app's, when there is one. */
40
+ export function participantServeUrl(subject) {
41
+ if (subject.kind === "clone" || subject.kind === "local-tree")
42
+ return subject.serve.url;
43
+ return "serveUrl" in subject ? subject.serveUrl : undefined;
44
+ }
@@ -1,13 +1,19 @@
1
1
  import type { AdmittedPlan, RunLabOptions } from "../run-lab.js";
2
2
  import type { LabPlan, PlanRefusal } from "../lab/plan-types.js";
3
3
  import type { RunResult } from "../run/results.js";
4
+ import { type StudyResultIdentity } from "../run/study-result.js";
4
5
  type PreviewPlan = Extract<LabPlan, {
5
6
  readonly route: "preview";
6
7
  }>;
8
+ /**
9
+ * The preview route's result when a study runs: the synthetic run's result, named as a study
10
+ * result. `humanish run` with no study returns the plain `RunResult`.
11
+ */
12
+ export type PreviewStudyResult = Omit<RunResult, "schema"> & StudyResultIdentity<"preview">;
7
13
  /** A refused preview's result. */
8
- export declare function previewLabRefusal(cwd: string, refusal: Extract<PlanRefusal, {
14
+ export declare function previewLabRefusal(cwd: string, studyId: string, refusal: Extract<PlanRefusal, {
9
15
  readonly route: "preview";
10
- }>): RunResult;
16
+ }>): PreviewStudyResult;
11
17
  /** runLab's step for a preview plan: it has no local checks and takes no scorer, so it returns its run. */
12
18
  export declare function admitPreviewPlan(plan: PreviewPlan, input: Pick<RunLabOptions, "cwd" | "runId" | "open">): AdmittedPlan<"preview">;
13
19
  export {};
@@ -1,11 +1,12 @@
1
1
  // The preview route: a lab whose subject is this repo runs the synthetic dry run. planLab decides
2
2
  // the sim count and refuses what a synthetic run would ignore; runPreviewPlan does the rest.
3
+ import { studyResultIdentity } from "../run/study-result.js";
3
4
  import { runDryRun } from "../run/dry-run.js";
4
5
  import path from "node:path";
5
6
  /** A refused preview's result. */
6
- export function previewLabRefusal(cwd, refusal) {
7
+ export function previewLabRefusal(cwd, studyId, refusal) {
7
8
  return {
8
- schema: "humanish.run-result.v1",
9
+ ...studyResultIdentity("preview", studyId),
9
10
  ok: false,
10
11
  cwd: path.resolve(cwd),
11
12
  warnings: [],
@@ -18,8 +19,10 @@ export function admitPreviewPlan(plan, input) {
18
19
  ok: true,
19
20
  run: async () => ({
20
21
  route: "preview",
21
- backend: "synthetic",
22
- result: await runPreviewPlan(plan, input),
22
+ result: {
23
+ ...(await runPreviewPlan(plan, input)),
24
+ ...studyResultIdentity("preview", plan.labId),
25
+ },
23
26
  }),
24
27
  };
25
28
  }
@@ -29,7 +32,7 @@ function runPreviewPlan(plan, input) {
29
32
  ...(plan.lab === undefined ? {} : { lab: plan.lab }),
30
33
  cwd: input.cwd,
31
34
  dryRun: true,
32
- simCount: plan.participantCount,
35
+ participantCount: plan.participantCount,
33
36
  ...(input.runId === undefined ? {} : { runId: input.runId }),
34
37
  ...(input.open === undefined ? {} : { observer: { open: input.open } }),
35
38
  });
@@ -2,15 +2,13 @@ import type { ActorPersonaRef } from "../../actors/contract.js";
2
2
  import type { ScriptedBrowserSessionResult } from "../../actors/scripted-browser/actor.js";
3
3
  import type { BrowserPersonaJourney, BrowserSurface } from "../../actors/scripted-browser/types.js";
4
4
  import type { DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
5
- import { type ReviewSummary, type RunBundle, type RunSubjectProvenance } from "../../run/bundle.js";
6
- import type { RunLabProvenance } from "../../run/status.js";
5
+ import { type ReviewSummary, type RunBundle, type RunSubjectProvenance, type BundleRun } from "../../run/bundle.js";
7
6
  /** What the scripted lab's bundle is built from. */
8
7
  interface ScriptedBundleArgs {
9
- /** Lab provenance for the bundle\'s own `lab` field (#455). */
10
- lab?: RunLabProvenance;
8
+ /** The run this bundle belongs to; the bundle head reads its id, mode, start and lab. */
9
+ run: BundleRun;
11
10
  actorId: string;
12
11
  appUrl: string;
13
- createdAt: string;
14
12
  desktopTemplate?: string;
15
13
  dryRun: boolean;
16
14
  hostDigest?: string;
@@ -18,7 +16,6 @@ interface ScriptedBundleArgs {
18
16
  labId: string;
19
17
  labTitle?: string;
20
18
  persona: ActorPersonaRef;
21
- runId: string;
22
19
  scenarioSource: string;
23
20
  scenarioSourceDigest: string;
24
21
  screenshotsBySurface: Map<string, string[]>;
@@ -37,8 +34,8 @@ interface ScriptedBundleArgs {
37
34
  verdict: ReviewSummary["verdict"];
38
35
  }
39
36
  /**
40
- * Project the scripted lab run into a humanish.run-bundle.v1 (no schema change — a new
41
- * producer only). The load-bearing line is `stream.actor = result.trace`: the provider-neutral
37
+ * Project the scripted lab run into a humanish.run-bundle.v1 (no schema change: a new
38
+ * producer only). The key line is `stream.actor = result.trace`: the provider-neutral
42
39
  * ActorTrace seam the Observer renders and verifyRun's engagement check reads. Exported for
43
40
  * the bundle-builder tests.
44
41
  */
@@ -1,5 +1,6 @@
1
1
  // Assemble the scripted-browser lab's run bundle from its sessions, and the review summary and
2
2
  // markdown that ship with it.
3
+ import { verdictText } from "../../run/judge.js";
3
4
  import { redactText } from "../../evidence/redaction.js";
4
5
  import { buildRunCostSummary, desktopSpanToMinutes, spendFreeCostSummary, } from "../../run/cost-summary.js";
5
6
  import { REVIEW_SCHEMA, bundleArtifacts, bundleHead, } from "../../run/bundle.js";
@@ -7,31 +8,26 @@ import {} from "../../run/streams.js";
7
8
  import { participantEvent, recordIdOf } from "../../run/participant-records.js";
8
9
  import { scriptedSurfaceIds, scriptedSurfaceRecords } from "./surface-records.js";
9
10
  /**
10
- * Project the scripted lab run into a humanish.run-bundle.v1 (no schema change — a new
11
- * producer only). The load-bearing line is `stream.actor = result.trace`: the provider-neutral
11
+ * Project the scripted lab run into a humanish.run-bundle.v1 (no schema change: a new
12
+ * producer only). The key line is `stream.actor = result.trace`: the provider-neutral
12
13
  * ActorTrace seam the Observer renders and verifyRun's engagement check reads. Exported for
13
14
  * the bundle-builder tests.
14
15
  */
15
16
  export function buildScriptedLabBundle(args) {
16
17
  const resultBySurface = new Map(args.sessionResults.map((result) => [result.capture.surface.id, result]));
17
- const records = args.surfaces.map((surface, index) => scriptedSurfaceRecords(args, surface, index, resultBySurface.get(surface.id), args.screenshotsBySurface.get(surface.id) ?? []));
18
+ // Each surface's records are stamped with the run's start.
19
+ const context = { ...args, createdAt: args.run.createdAt };
20
+ const records = args.surfaces.map((surface, index) => scriptedSurfaceRecords(context, surface, index, resultBySurface.get(surface.id), args.screenshotsBySurface.get(surface.id) ?? []));
18
21
  const events = scriptedEvents(args);
19
22
  const review = buildScriptedReview(args);
20
23
  const ranLive = args.sessionResults.length > 0 || args.sessionError !== undefined;
21
24
  const cost = args.dryRun ? undefined : scriptedCost(args.subjectDesktop);
22
25
  return {
23
- ...bundleHead({
24
- runId: args.runId,
25
- mode: args.dryRun ? "dry-run" : "live",
26
- participants: args.surfaces.length,
27
- createdAt: args.createdAt,
28
- ...(args.lab === undefined ? {} : { lab: args.lab }),
29
- source: args.source,
30
- }),
26
+ ...bundleHead(args.run, { participants: args.surfaces.length, source: args.source }),
31
27
  persona: {
32
28
  id: args.persona.id,
33
29
  name: `Scripted journey persona (${args.persona.id})`,
34
- source: `lab:${args.labId}`,
30
+ source: `study:${args.labId}`,
35
31
  sourceDigest: args.persona.promptDigest,
36
32
  },
37
33
  scenario: {
@@ -43,7 +39,7 @@ export function buildScriptedLabBundle(args) {
43
39
  },
44
40
  lifecycle: [
45
41
  {
46
- at: args.createdAt,
42
+ at: args.run.createdAt,
47
43
  event: "scripted-lab.run.created",
48
44
  message: `Created scripted-browser lab run with ${args.surfaces.length} surface${args.surfaces.length === 1 ? "" : "s"} (actor ${args.actorId}).`,
49
45
  },
@@ -54,8 +50,8 @@ export function buildScriptedLabBundle(args) {
54
50
  redaction: {
55
51
  status: "passed",
56
52
  notes: ranLive
57
- ? "Scripted step URLs are sanitized to loopback origin+path (query/hash redacted) and step text passes text redaction. Screenshots are FULL-FIDELITY (raw), retained for local use in gitignored .humanish — NOT redacted for publishing; policies.redactScreenshots is not yet supported on this route."
58
- : "Dry-run contract bundle: no browser ran and no screenshots were captured. The scenario contract is digest-pinned; live step text passes text redaction when a session runs.",
53
+ ? "Scripted step URLs are reduced to loopback origin and path (query and hash removed), and step text passes text redaction. Screenshots are unblurred and kept for local use in the gitignored .humanish/ folder; they are not redacted for publishing, and policies.redactScreenshots is not supported on this route yet."
54
+ : "Dry-run bundle: no browser ran and no screenshots were captured. The scenario is digest-pinned; live step text passes text redaction when a session runs.",
59
55
  },
60
56
  artifacts: bundleArtifacts(),
61
57
  review,
@@ -70,25 +66,25 @@ function scriptedEvents(args) {
70
66
  const events = [
71
67
  {
72
68
  id: "event-000-created",
73
- at: args.createdAt,
69
+ at: args.run.createdAt,
74
70
  level: "info",
75
71
  type: "scripted-lab.run.created",
76
72
  message: `Created scripted-browser lab run for ${args.labId} (actor ${args.actorId}, ${args.surfaces.length} surface${args.surfaces.length === 1 ? "" : "s"}).`,
77
73
  },
78
74
  {
79
75
  id: "event-001-subject",
80
- at: args.createdAt,
76
+ at: args.run.createdAt,
81
77
  level: "info",
82
78
  type: "scripted-lab.subject.declared",
83
- // Invariant 5: provenance recorded or its absence DECLARED. The lab did not provision
79
+ // Provenance is recorded or its absence declared. The lab did not provision
84
80
  // this subject on app-url routes; clone routes carry structured subject provenance below.
85
81
  message: args.subject
86
82
  ? `Provisioned synthetic subject: clone of ${args.subject.repo}${args.subject.commit ? `@${args.subject.commit}` : ""}, served + getHost-exposed in-sandbox; env names: ${args.subject.envNames?.join(", ") || "none"} (values never persisted); state provenance: ${args.subject.state.provenance}; evidence host digest: ${args.hostDigest ?? "dry-run"}.`
87
- : `Subject app declared at ${args.appUrl}; the lab did not provision it — subject build/commit provenance is UNPINNED; evidence binds to the scenario digest ${args.scenarioSourceDigest}.`,
83
+ : `Subject app declared at ${args.appUrl}; humanish did not provision it, so its build and commit are unpinned. The evidence is tied to the scenario digest ${args.scenarioSourceDigest}.`,
88
84
  },
89
85
  {
90
86
  id: "event-002-spend",
91
- at: args.createdAt,
87
+ at: args.run.createdAt,
92
88
  level: "info",
93
89
  type: "scripted-lab.spend",
94
90
  message: args.subject
@@ -103,14 +99,14 @@ function scriptedEvents(args) {
103
99
  at: result.capture.capturedAt,
104
100
  level: result.status === "passed" ? "info" : "warn",
105
101
  type: `scripted-lab.session.${result.completionReason}`,
106
- message: `${result.capture.surface.id}: ${result.status} — ${result.reason}`,
102
+ message: `${result.capture.surface.id}: ${result.status} (${result.reason})`,
107
103
  }));
108
104
  }
109
105
  }
110
106
  else if (args.sessionError !== undefined) {
111
107
  events.push({
112
108
  id: "event-003-session-error",
113
- at: args.createdAt,
109
+ at: args.run.createdAt,
114
110
  level: "error",
115
111
  type: "scripted-lab.session.error",
116
112
  message: args.sessionError,
@@ -119,10 +115,10 @@ function scriptedEvents(args) {
119
115
  else {
120
116
  events.push({
121
117
  id: "event-003-contract",
122
- at: args.createdAt,
118
+ at: args.run.createdAt,
123
119
  level: "info",
124
120
  type: "scripted-lab.contract.ready",
125
- message: `Dry-run contract bundle ready: scenario ${args.journey.scenarioId} @ ${args.scenarioSourceDigest} (${args.scenarioSource}, ${args.journey.steps.length} step${args.journey.steps.length === 1 ? "" : "s"}) parsed and digest-pinned; switch scenario.mode to live to actuate a real browser.`,
121
+ message: `Dry-run bundle ready: scenario ${args.journey.scenarioId} @ ${args.scenarioSourceDigest} (${args.scenarioSource}, ${args.journey.steps.length} step${args.journey.steps.length === 1 ? "" : "s"}) parsed and digest-pinned; switch scenario.mode to live to actuate a real browser.`,
126
122
  });
127
123
  }
128
124
  return events;
@@ -156,8 +152,8 @@ function buildScriptedReview(args) {
156
152
  return {
157
153
  schema: REVIEW_SCHEMA,
158
154
  verdict: args.verdict,
159
- summary: `Dry-run contract for scenario ${args.journey.scenarioId} (${args.scenarioSource}, ${args.journey.steps.length} steps) against ${args.appUrl}: composition and scenario contract proven at $0; no browser ran.`,
160
- gaps: ["Live scripted session not yet run (dry-run contract only)."],
155
+ summary: `Dry run of scenario ${args.journey.scenarioId} (${args.scenarioSource}, ${args.journey.steps.length} steps) against ${args.appUrl}: composition and scenario checked at $0; no browser ran.`,
156
+ gaps: ["Live scripted session not yet run (dry run only)."],
161
157
  };
162
158
  }
163
159
  const passed = args.sessionResults.filter((result) => result.status === "passed").length;
@@ -181,7 +177,7 @@ export function renderScriptedReviewMarkdown(bundle) {
181
177
  "",
182
178
  `- run: ${bundle.runId}`,
183
179
  `- mode: ${bundle.mode}`,
184
- `- verdict: ${bundle.review.verdict}`,
180
+ `- verdict: ${verdictText(bundle.review.verdict, bundle.mode)}`,
185
181
  `- summary: ${bundle.review.summary}`,
186
182
  `- scenario: ${bundle.scenario.id} @ ${bundle.scenario.sourceDigest} (${bundle.scenario.source})`,
187
183
  ...(subject ? [`- subject: ${subject.message}`] : []),
@@ -1,8 +1,8 @@
1
+ import type { LabDeps } from "../../lab/lab-deps.js";
1
2
  import type { RoutePlanResult, RouteRefusal, ScriptedPlan } from "../../lab/plan-types.js";
2
3
  import type { LabConfig } from "../../lab/types.js";
3
- import type { RunLabProvenance } from "../../run/status.js";
4
4
  /** The error a scripted lab returns before a run starts. */
5
- export interface ScriptedRefusal extends RouteRefusal<"scripted", "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE"> {
5
+ export interface ScriptedRefusal extends RouteRefusal<"scripted", "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_SCRIPTED_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_SUBJECT_UNSAFE"> {
6
6
  /**
7
7
  * Set on the receiving, analysis and tasks refusals. The route returns those before it opens its
8
8
  * run scope, so their result has its own field order and no automatic-analysis record.
@@ -15,16 +15,14 @@ export interface ScriptedRefusal extends RouteRefusal<"scripted", "HUMANISH_LAB_
15
15
  export type ScriptedPlanResult = RoutePlanResult<ScriptedPlan, ScriptedRefusal>;
16
16
  /** The app URL a run's evidence names: a provisioned subject's getHost URL is never persisted. */
17
17
  export declare function evidenceAppUrlOf(subject: ScriptedPlan["subject"]): string;
18
+ /** Whether a test injected the browser, so a live run needs no host browser. */
19
+ export declare function injectedBrowser(deps: LabDeps | undefined): boolean;
18
20
  /**
19
21
  * Plan a scripted-browser lab. It is called for any config handed to the scripted runner, not only
20
22
  * one routeOf sends here, so a config for another route gets this route's refusal.
21
23
  */
22
24
  export declare function planScriptedLab(config: LabConfig, input: {
23
25
  readonly dryRun: boolean;
24
- readonly lab?: RunLabProvenance;
25
- /** An injected browser means a live run needs no host browser. */
26
- readonly hooks?: {
27
- readonly launchBrowser?: unknown;
28
- readonly browserCommand?: string;
29
- };
26
+ /** A test's injected browser means a live run needs no host browser. */
27
+ readonly injectedBrowser?: boolean;
30
28
  }): ScriptedPlanResult;
@@ -7,13 +7,17 @@ import { browserSurfaces } from "../../actors/scripted-browser/types.js";
7
7
  import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
8
8
  import { isNonEmpty, planBase, provisionedSubject } from "../../lab/plan-base.js";
9
9
  import { cloneTargetValidationReason, desktopMediaValidationReason, taskProtocolValidationReason, } from "../../lab/validation.js";
10
- // Default surface roster is 1 (desktop only): the defaults-table single-lane row governs;
10
+ // Default surface roster is 1 (desktop only): the defaults-table single-participant row governs;
11
11
  // `count: 2` is the declared override that adds the mobile surface.
12
12
  const DEFAULT_SURFACE_COUNT = 1;
13
13
  /** The app URL a run's evidence names: a provisioned subject's getHost URL is never persisted. */
14
14
  export function evidenceAppUrlOf(subject) {
15
15
  return subject.kind === "clone" ? "[provisioned-subject]" : subject.appUrl;
16
16
  }
17
+ /** Whether a test injected the browser, so a live run needs no host browser. */
18
+ export function injectedBrowser(deps) {
19
+ return Boolean(deps?.launchBrowser || deps?.browserCommand);
20
+ }
17
21
  /**
18
22
  * Plan a scripted-browser lab. It is called for any config handed to the scripted runner, not only
19
23
  * one routeOf sends here, so a config for another route gets this route's refusal.
@@ -25,23 +29,23 @@ export function planScriptedLab(config, input) {
25
29
  });
26
30
  const beforeScope = { beforeScope: true };
27
31
  if (String(config.comms?.email?.kind) === "real")
28
- return refuse("HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID", "Real email receiving is unsupported on the scripted route. Use a supported hosted computer-use browser lab.", beforeScope);
32
+ return refuse("HUMANISH_SCRIPTED_SCENARIO_INVALID", "Real email receiving is unsupported on the scripted route. Use a supported hosted computer-use browser lab.", beforeScope);
29
33
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
30
34
  if (!analysis.ok)
31
- return refuse("HUMANISH_LAB_ANALYSIS_INVALID", analysis.message, beforeScope);
35
+ return refuse("HUMANISH_STUDY_ANALYSIS_INVALID", analysis.message, beforeScope);
32
36
  const tasksReason = taskProtocolValidationReason(config, false);
33
37
  if (tasksReason)
34
- return refuse("HUMANISH_LAB_TASKS_UNSUPPORTED", tasksReason, beforeScope);
38
+ return refuse("HUMANISH_STUDY_TASKS_UNSUPPORTED", tasksReason, beforeScope);
35
39
  const mediaReason = desktopMediaValidationReason(config);
36
40
  if (mediaReason)
37
- return refuse("HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID", mediaReason);
41
+ return refuse("HUMANISH_SCRIPTED_SCENARIO_INVALID", mediaReason);
38
42
  const cloneTargetReason = cloneTargetValidationReason(config);
39
43
  if (cloneTargetReason)
40
- return refuse("HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE", cloneTargetReason);
44
+ return refuse("HUMANISH_SCRIPTED_SUBJECT_UNSAFE", cloneTargetReason);
41
45
  const actorType = config.actors[0]?.type ?? "";
42
46
  const descriptor = actorRegistry[actorType];
43
47
  if (!descriptor || !isScriptedBrowserActorDescriptor(descriptor))
44
- return refuse("HUMANISH_SCRIPTED_LAB_ACTOR_UNSUPPORTED", `actors[0].type "${actorType}" is not a registered scripted-browser actor.`);
48
+ return refuse("HUMANISH_SCRIPTED_ACTOR_UNSUPPORTED", `actors[0].type "${actorType}" is not a registered scripted-browser actor.`);
45
49
  const actor = descriptor.id;
46
50
  // The parser checks the loopback entry too; a library caller skips the parser. A clone's URL is
47
51
  // minted by getHost during the run, and its evidence names only the placeholder.
@@ -49,20 +53,19 @@ export function planScriptedLab(config, input) {
49
53
  if (config.subject.source === "clone") {
50
54
  const provisioned = provisionedSubject(config);
51
55
  if (provisioned?.kind !== "clone" || !provisioned.repo)
52
- return refuse("HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE", "clone scripted-browser labs require one subject repo plus subject.serve; parseLabConfig should have rejected this config.", { actor, appUrl: "[provisioned-subject]" });
56
+ return refuse("HUMANISH_SCRIPTED_SUBJECT_UNSAFE", "clone scripted-browser labs require one subject repo plus subject.serve; parseLabConfig should have rejected this config.", { actor, appUrl: "[provisioned-subject]" });
53
57
  subject = provisioned;
54
58
  }
55
59
  else {
56
60
  const appUrl = normalizeLocalAppUrl(config.subject.appUrl ?? "");
57
61
  if (!appUrl)
58
- return refuse("HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE", "subject.appUrl must be a loopback http(s) URL (127.0.0.1 or localhost) on the scripted-browser route.", { actor });
62
+ return refuse("HUMANISH_SCRIPTED_SUBJECT_UNSAFE", "subject.appUrl must be a loopback http(s) URL (127.0.0.1 or localhost) on the scripted-browser route.", { actor });
59
63
  subject = { kind: "loopback", appUrl };
60
64
  }
61
65
  // The steps are the actor, so there is no built-in journey to fall back on.
62
66
  const scenarioRef = config.scenario?.ref;
63
67
  if (!scenarioRef?.trim())
64
- return refuse("HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID", "scripted-browser labs require `scenario.ref` — the committed scenario's browser steps are what this actor executes.", { actor, appUrl: evidenceAppUrlOf(subject) });
65
- const hooks = input.hooks ?? {};
68
+ return refuse("HUMANISH_SCRIPTED_SCENARIO_INVALID", "A scripted-browser study needs `scenario.ref`: the actor runs the browser steps in that scenario file.", { actor, appUrl: evidenceAppUrlOf(subject) });
66
69
  const requirements = [];
67
70
  if (!input.dryRun && subject.kind === "clone") {
68
71
  requirements.push({ kind: "key", name: "E2B_API_KEY" });
@@ -70,7 +73,7 @@ export function planScriptedLab(config, input) {
70
73
  requirements.push({ kind: "subject-env", names: subject.env });
71
74
  }
72
75
  // The browser runs on this machine on both subjects; a clone's is pointed at its getHost URL.
73
- if (!input.dryRun && !hooks.launchBrowser && !hooks.browserCommand)
76
+ if (!input.dryRun && input.injectedBrowser !== true)
74
77
  requirements.push({ kind: "host-browser" });
75
78
  const persona = config.actors[0]?.persona;
76
79
  const timeoutMs = config.execution?.timeoutMs;
@@ -79,7 +82,6 @@ export function planScriptedLab(config, input) {
79
82
  plan: {
80
83
  ...planBase(config, {
81
84
  dryRun: input.dryRun,
82
- ...(input.lab === undefined ? {} : { lab: input.lab }),
83
85
  analysis,
84
86
  }),
85
87
  route: "scripted",
@@ -36,13 +36,16 @@ export interface ScriptedFinishInputs {
36
36
  }
37
37
  /**
38
38
  * The scripted run's execution failures: the session's own error, a live surface that never
39
- * returned, a surface that ended in a harness error, and an Observer that failed.
39
+ * returned, a surface that ended in a harness error, a subject sandbox whose release is
40
+ * unconfirmed, and an Observer that failed.
40
41
  */
41
42
  export declare function scriptedExecutionFailures(args: {
42
43
  dryRun: boolean;
44
+ runId: string;
43
45
  sessionError: string | undefined;
44
46
  expected: number;
45
47
  sessionResults: readonly Pick<ScriptedBrowserSessionResult, "completionReason" | "reason">[];
48
+ subject: Pick<ScriptedSubject, "sandboxId" | "killed" | "releaseWarning"> | undefined;
46
49
  observer: Pick<ObserverResult, "ok" | "error">;
47
50
  }): ExecutionFailure[];
48
51
  export declare function finishScriptedRun(inputs: ScriptedFinishInputs): Promise<ScriptedBrowserLabResult>;
@@ -1,9 +1,10 @@
1
- import { judgeExecution, judgeScripted, OUTCOME_POLICIES, resultOk, } from "../../run/judge.js";
1
+ import { judgeExecution, sandboxCleanupFailure, judgeScripted, OUTCOME_POLICIES, resultOk, } from "../../run/judge.js";
2
2
  import { validatePreparedRunArtifactPaths } from "../../run/paths.js";
3
3
  import { resolveSubjectState } from "../computer-use/subject-projection.js";
4
4
  import { buildScriptedLabBundle } from "./bundle.js";
5
5
  import { existingScreenshots } from "./session-result.js";
6
- import { SCRIPTED_BROWSER_LAB_SCHEMA } from "./types.js";
6
+ import {} from "./types.js";
7
+ import { studyResultIdentity } from "../../run/study-result.js";
7
8
  /** What judgeScripted reads from one surface's session. Scripted has no engagement or blocker rule. */
8
9
  function scriptedSurfaceFacts(result) {
9
10
  return {
@@ -16,7 +17,8 @@ function scriptedSurfaceFacts(result) {
16
17
  }
17
18
  /**
18
19
  * The scripted run's execution failures: the session's own error, a live surface that never
19
- * returned, a surface that ended in a harness error, and an Observer that failed.
20
+ * returned, a surface that ended in a harness error, a subject sandbox whose release is
21
+ * unconfirmed, and an Observer that failed.
20
22
  */
21
23
  export function scriptedExecutionFailures(args) {
22
24
  const { sessionError, sessionResults, observer } = args;
@@ -39,6 +41,9 @@ export function scriptedExecutionFailures(args) {
39
41
  },
40
42
  ]
41
43
  : []),
44
+ ...(args.subject?.sandboxId === undefined || args.subject.killed
45
+ ? []
46
+ : [sandboxCleanupFailure("subject", args.subject.releaseWarning, args.runId)]),
42
47
  ...(observer.ok
43
48
  ? []
44
49
  : [
@@ -54,7 +59,7 @@ export async function finishScriptedRun(inputs) {
54
59
  const { surfaces, sessionResults, sessionError, warnings, clone, redactRepoLabel } = inputs;
55
60
  const { subjectEnvNames, scriptedSubject } = inputs;
56
61
  const { actor, dryRun } = plan;
57
- const { runId, createdAt, paths: runPaths } = run;
62
+ const { runId, paths: runPaths } = run;
58
63
  const subjectCommit = scriptedSubject?.commit;
59
64
  const subjectSandboxId = scriptedSubject?.sandboxId;
60
65
  const subjectKilled = scriptedSubject?.killed ?? false;
@@ -86,16 +91,14 @@ export async function finishScriptedRun(inputs) {
86
91
  surfaces: sessionResults.map(scriptedSurfaceFacts),
87
92
  });
88
93
  const bundle = buildScriptedLabBundle({
89
- ...(plan.lab === undefined ? {} : { lab: plan.lab }),
94
+ run,
90
95
  actorId: actor,
91
96
  appUrl: evidenceAppUrl,
92
- createdAt,
93
97
  dryRun,
94
98
  journey,
95
99
  labId: plan.labId,
96
100
  ...(plan.title ? { labTitle: plan.title } : {}),
97
101
  persona,
98
- runId,
99
102
  scenarioSource: scenario.source,
100
103
  scenarioSourceDigest: scenario.sourceDigest,
101
104
  screenshotsBySurface,
@@ -114,7 +117,7 @@ export async function finishScriptedRun(inputs) {
114
117
  const finished = await run.finish(bundle);
115
118
  // Surface the local-fidelity posture so the operator knows the bundle is not publish-safe as-is.
116
119
  if (sessionResults.some((result) => result.trace.redaction.screenshots === "raw")) {
117
- warnings.push("Screenshots are full-fidelity (raw) for local use — the bundle stays in gitignored .humanish and nothing scans these pixels; review them before sharing anywhere. policies.redactScreenshots is not yet supported on the scripted route.");
120
+ warnings.push("Screenshots are unblurred for local use: the bundle stays in the gitignored .humanish/ folder and nothing scans these pixels, so review them before sharing. policies.redactScreenshots is not supported on the scripted route yet.");
118
121
  }
119
122
  const observer = await finished.renderObserver();
120
123
  await validatePreparedRunArtifactPaths(runPaths);
@@ -122,19 +125,20 @@ export async function finishScriptedRun(inputs) {
122
125
  const policy = OUTCOME_POLICIES.scripted;
123
126
  const execution = judgeExecution(scriptedExecutionFailures({
124
127
  dryRun,
128
+ runId,
125
129
  sessionError,
126
130
  expected: surfaces.length,
127
131
  sessionResults,
132
+ subject: scriptedSubject,
128
133
  observer,
129
134
  }), policy);
130
135
  const ok = resultOk({ judgment, execution, scorerFailures: [], policy });
131
136
  await finished.recordOutcome({ ok, execution });
132
137
  const harnessErrorSession = sessionResults.find((result) => result.completionReason === "harness_error");
133
138
  return {
134
- schema: SCRIPTED_BROWSER_LAB_SCHEMA,
139
+ ...studyResultIdentity("scripted", plan.labId),
135
140
  ok,
136
141
  cwd,
137
- labId: plan.labId,
138
142
  actor,
139
143
  appUrl: evidenceAppUrl,
140
144
  dryRun,
@@ -163,7 +167,7 @@ export async function finishScriptedRun(inputs) {
163
167
  ? {}
164
168
  : {
165
169
  error: {
166
- code: "HUMANISH_SCRIPTED_LAB_FAILED",
170
+ code: "HUMANISH_SCRIPTED_FAILED",
167
171
  message: sessionError ??
168
172
  (observer.ok
169
173
  ? harnessErrorSession