humanish 0.106.1 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/AGENTS.md +4 -4
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +14 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -8
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +30 -3
  16. package/dist/actors/codex/qualified-versions.js +50 -5
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +9 -7
  45. package/dist/actors/local-agent/cli.js +1 -1
  46. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  47. package/dist/actors/scripted-browser/journey.js +15 -4
  48. package/dist/actors/scripted-browser/steps.js +18 -0
  49. package/dist/actors/scripted-browser/types.d.ts +11 -1
  50. package/dist/actors/stop-conditions.js +1 -3
  51. package/dist/analysis/automatic-completion.d.ts +13 -8
  52. package/dist/analysis/automatic-completion.js +14 -8
  53. package/dist/analysis/automatic-config.d.ts +1 -1
  54. package/dist/analysis/automatic-config.js +2 -2
  55. package/dist/analysis/automatic.d.ts +10 -4
  56. package/dist/analysis/automatic.js +17 -13
  57. package/dist/analysis/diagnostics.d.ts +23 -0
  58. package/dist/analysis/diagnostics.js +112 -0
  59. package/dist/analysis/evidence-sources.js +2 -2
  60. package/dist/analysis/evidence.js +6 -6
  61. package/dist/analysis/execute.d.ts +7 -1
  62. package/dist/analysis/execute.js +39 -12
  63. package/dist/analysis/job.d.ts +8 -5
  64. package/dist/analysis/job.js +15 -14
  65. package/dist/analysis/load.d.ts +1 -1
  66. package/dist/analysis/load.js +5 -5
  67. package/dist/analysis/provider.d.ts +9 -1
  68. package/dist/analysis/restricted-codex.d.ts +2 -0
  69. package/dist/analysis/restricted-codex.js +10 -1
  70. package/dist/analysis/service.d.ts +2 -0
  71. package/dist/analysis/service.js +31 -12
  72. package/dist/analysis/sharing.d.ts +2 -2
  73. package/dist/analysis/sharing.js +5 -5
  74. package/dist/analysis/store-executions.d.ts +5 -5
  75. package/dist/analysis/store-executions.js +12 -12
  76. package/dist/analysis/store.d.ts +4 -4
  77. package/dist/analysis/store.js +13 -13
  78. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  79. package/dist/cli/commands/analysis-signals.js +4 -1
  80. package/dist/cli/commands/analyze.js +4 -2
  81. package/dist/cli/commands/comms.js +8 -1
  82. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  83. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  84. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  85. package/dist/cli/commands/lab-route-preview.js +3 -4
  86. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  87. package/dist/cli/commands/lab-route-run.js +6 -2
  88. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  89. package/dist/cli/commands/lab-route-scripted.js +0 -1
  90. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  91. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  92. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  93. package/dist/cli/commands/lab-route-terminal.js +0 -1
  94. package/dist/cli/commands/lab-run.js +76 -45
  95. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  96. package/dist/cli/commands/lab.js +12 -6
  97. package/dist/cli/commands/observe.js +22 -0
  98. package/dist/cli/commands/run-signals.d.ts +30 -0
  99. package/dist/cli/commands/run-signals.js +146 -0
  100. package/dist/cli/commands/runs.js +10 -8
  101. package/dist/cli/commands/watch.js +12 -10
  102. package/dist/cli/doctor.d.ts +3 -0
  103. package/dist/cli/doctor.js +10 -2
  104. package/dist/cli/io.d.ts +5 -4
  105. package/dist/cli/io.js +12 -8
  106. package/dist/cli/program.js +3 -3
  107. package/dist/cli/renamed-options.d.ts +11 -0
  108. package/dist/cli/renamed-options.js +18 -0
  109. package/dist/cli/telemetry.d.ts +2 -2
  110. package/dist/cli/telemetry.js +1 -1
  111. package/dist/comms/capture-surface.d.ts +1 -1
  112. package/dist/comms/catch-host.d.ts +1 -1
  113. package/dist/comms/connections.js +4 -4
  114. package/dist/comms/external-evidence.d.ts +27 -0
  115. package/dist/comms/external-evidence.js +93 -0
  116. package/dist/comms/lease-store.js +7 -7
  117. package/dist/comms/types.js +1 -1
  118. package/dist/evidence/browser-hygiene.d.ts +1 -1
  119. package/dist/evidence/browser-hygiene.js +1 -1
  120. package/dist/evidence/redaction.js +1 -1
  121. package/dist/evidence/secret-scrub.d.ts +9 -0
  122. package/dist/evidence/secret-scrub.js +96 -0
  123. package/dist/feedback/draft.js +7 -9
  124. package/dist/feedback/export-bundle.js +4 -4
  125. package/dist/feedback/export.js +9 -9
  126. package/dist/feedback/feedback.d.ts +1 -1
  127. package/dist/index.d.ts +3 -6
  128. package/dist/index.js +3 -6
  129. package/dist/keys/key-resolution.d.ts +3 -1
  130. package/dist/keys/key-resolution.js +18 -16
  131. package/dist/lab/adapter-extension.d.ts +28 -6
  132. package/dist/lab/adapter-extension.js +65 -126
  133. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  134. package/dist/lab/adapter-scorer-loader.js +24 -0
  135. package/dist/lab/composition-rules.js +20 -20
  136. package/dist/lab/config.js +28 -26
  137. package/dist/lab/device-presets.d.ts +2 -2
  138. package/dist/lab/discover.js +1 -3
  139. package/dist/lab/doctor.d.ts +44 -9
  140. package/dist/lab/doctor.js +149 -41
  141. package/dist/lab/init-plan.js +1 -3
  142. package/dist/lab/keys.js +1 -1
  143. package/dist/lab/lab-deps.d.ts +85 -0
  144. package/dist/lab/lab-deps.js +4 -0
  145. package/dist/lab/parse/actors.js +8 -7
  146. package/dist/lab/parse/comms.js +3 -2
  147. package/dist/lab/parse/execution.js +3 -2
  148. package/dist/lab/parse/subject-state.js +2 -1
  149. package/dist/lab/parse/subject.js +2 -1
  150. package/dist/lab/parse/values.d.ts +0 -1
  151. package/dist/lab/parse/values.js +0 -3
  152. package/dist/lab/persona-resolve.d.ts +3 -3
  153. package/dist/lab/persona-resolve.js +4 -4
  154. package/dist/lab/persona.js +1 -3
  155. package/dist/lab/plan-base.d.ts +0 -2
  156. package/dist/lab/plan-base.js +6 -4
  157. package/dist/lab/plan-participants.d.ts +5 -5
  158. package/dist/lab/plan-participants.js +2 -2
  159. package/dist/lab/plan-types.d.ts +22 -4
  160. package/dist/lab/plan.d.ts +3 -11
  161. package/dist/lab/plan.js +18 -42
  162. package/dist/lab/preflight-result.js +0 -2
  163. package/dist/lab/preflight.d.ts +0 -3
  164. package/dist/lab/preflight.js +1 -1
  165. package/dist/lab/requirements.d.ts +20 -0
  166. package/dist/lab/requirements.js +54 -0
  167. package/dist/lab/route-inputs.d.ts +23 -12
  168. package/dist/lab/route-inputs.js +48 -51
  169. package/dist/lab/routing.d.ts +19 -24
  170. package/dist/lab/routing.js +14 -47
  171. package/dist/lab/run-lab-events.d.ts +6 -11
  172. package/dist/lab/run-lab-events.js +3 -11
  173. package/dist/lab/run-lab-homes.d.ts +64 -0
  174. package/dist/lab/run-lab-homes.js +3 -0
  175. package/dist/lab/run-lab-options.d.ts +12 -66
  176. package/dist/lab/run-lab-options.js +45 -275
  177. package/dist/lab/summary.d.ts +9 -4
  178. package/dist/lab/summary.js +15 -8
  179. package/dist/lab/types.d.ts +132 -132
  180. package/dist/lab/validation.d.ts +15 -15
  181. package/dist/lab/validation.js +28 -28
  182. package/dist/lab/warnings.js +20 -19
  183. package/dist/observer/artifact.d.ts +1 -1
  184. package/dist/observer/artifact.js +3 -3
  185. package/dist/observer/data.js +2 -2
  186. package/dist/observer/render.js +2 -2
  187. package/dist/observer/run-routes.d.ts +1 -1
  188. package/dist/observer/run-routes.js +5 -5
  189. package/dist/observer/serve.d.ts +17 -0
  190. package/dist/observer/serve.js +34 -3
  191. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  192. package/dist/routes/computer-use/bundle-parts.js +10 -3
  193. package/dist/routes/computer-use/bundle.d.ts +4 -11
  194. package/dist/routes/computer-use/bundle.js +9 -15
  195. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  196. package/dist/routes/computer-use/diagnostics.js +1 -1
  197. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  198. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  199. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  200. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  201. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  202. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  203. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  204. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  205. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  206. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  207. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  208. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  209. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  210. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  211. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  212. package/dist/routes/computer-use/external-comms.js +19 -43
  213. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  214. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  215. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  216. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  217. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  218. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  219. package/dist/routes/computer-use/live-flush.js +19 -27
  220. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +12 -11
  221. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  222. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  223. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  224. package/dist/routes/computer-use/local-vm.js +39 -66
  225. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  226. package/dist/routes/computer-use/participant-desktop.js +5 -25
  227. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  228. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  229. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  230. package/dist/routes/computer-use/participant-facts.js +12 -1
  231. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  232. package/dist/routes/computer-use/participant-model.js +49 -25
  233. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  234. package/dist/routes/computer-use/participant-prompt.js +4 -4
  235. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  236. package/dist/routes/computer-use/participant-runs.js +8 -8
  237. package/dist/routes/computer-use/plan.d.ts +21 -29
  238. package/dist/routes/computer-use/plan.js +52 -60
  239. package/dist/routes/computer-use/preflight.d.ts +3 -5
  240. package/dist/routes/computer-use/preflight.js +20 -16
  241. package/dist/routes/computer-use/rerun-selection.js +10 -6
  242. package/dist/routes/computer-use/result.d.ts +1 -1
  243. package/dist/routes/computer-use/result.js +40 -30
  244. package/dist/routes/computer-use/route.d.ts +3 -4
  245. package/dist/routes/computer-use/route.js +21 -19
  246. package/dist/routes/computer-use/self-report.d.ts +2 -2
  247. package/dist/routes/computer-use/self-report.js +4 -4
  248. package/dist/routes/computer-use/setup.d.ts +8 -14
  249. package/dist/routes/computer-use/setup.js +96 -72
  250. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  251. package/dist/routes/computer-use/single-bundle.js +20 -25
  252. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  253. package/dist/routes/computer-use/subject-projection.js +20 -19
  254. package/dist/routes/computer-use/types.d.ts +169 -210
  255. package/dist/routes/computer-use/types.js +13 -5
  256. package/dist/routes/preview.js +0 -1
  257. package/dist/routes/scripted/bundle.d.ts +3 -6
  258. package/dist/routes/scripted/bundle.js +11 -16
  259. package/dist/routes/scripted/plan.d.ts +5 -7
  260. package/dist/routes/scripted/plan.js +6 -4
  261. package/dist/routes/scripted/result.d.ts +4 -1
  262. package/dist/routes/scripted/result.js +10 -6
  263. package/dist/routes/scripted/route.js +10 -11
  264. package/dist/routes/scripted/scenario.d.ts +1 -1
  265. package/dist/routes/scripted/scenario.js +1 -1
  266. package/dist/routes/scripted/setup.d.ts +3 -2
  267. package/dist/routes/scripted/setup.js +22 -21
  268. package/dist/routes/scripted/subject.d.ts +8 -3
  269. package/dist/routes/scripted/subject.js +9 -5
  270. package/dist/routes/scripted/surface-records.js +1 -1
  271. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  272. package/dist/routes/scripted/surface-sessions.js +4 -4
  273. package/dist/routes/scripted/types.d.ts +19 -36
  274. package/dist/routes/scripted/types.js +1 -2
  275. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  276. package/dist/routes/shared-world/bundle.d.ts +2 -2
  277. package/dist/routes/shared-world/bundle.js +22 -26
  278. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  279. package/dist/routes/shared-world/checkpoints.js +4 -4
  280. package/dist/routes/shared-world/comms.d.ts +5 -4
  281. package/dist/routes/shared-world/comms.js +28 -41
  282. package/dist/routes/shared-world/external-public.d.ts +5 -5
  283. package/dist/routes/shared-world/external-public.js +19 -20
  284. package/dist/routes/shared-world/handoff.d.ts +4 -4
  285. package/dist/routes/shared-world/handoff.js +50 -50
  286. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  287. package/dist/routes/shared-world/lobby-code.js +13 -13
  288. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  289. package/dist/routes/shared-world/{seats.js → participant-specs.js} +43 -48
  290. package/dist/routes/shared-world/plan.d.ts +2 -6
  291. package/dist/routes/shared-world/plan.js +1 -2
  292. package/dist/routes/shared-world/provenance.d.ts +4 -4
  293. package/dist/routes/shared-world/provenance.js +4 -4
  294. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  295. package/dist/routes/shared-world/provisioned.js +46 -40
  296. package/dist/routes/shared-world/result.js +31 -19
  297. package/dist/routes/shared-world/route.js +37 -41
  298. package/dist/routes/shared-world/setup.d.ts +5 -4
  299. package/dist/routes/shared-world/setup.js +12 -14
  300. package/dist/routes/shared-world/types.d.ts +53 -126
  301. package/dist/routes/shared-world/types.js +2 -2
  302. package/dist/routes/terminal/adapter.d.ts +8 -8
  303. package/dist/routes/terminal/adapter.js +28 -125
  304. package/dist/routes/terminal/bundle.d.ts +7 -12
  305. package/dist/routes/terminal/bundle.js +24 -34
  306. package/dist/routes/terminal/credentials.d.ts +2 -2
  307. package/dist/routes/terminal/credentials.js +16 -16
  308. package/dist/routes/terminal/dry-run.d.ts +1 -1
  309. package/dist/routes/terminal/dry-run.js +9 -11
  310. package/dist/routes/terminal/encoding.d.ts +1 -1
  311. package/dist/routes/terminal/encoding.js +2 -2
  312. package/dist/routes/terminal/ledger.d.ts +6 -6
  313. package/dist/routes/terminal/ledger.js +9 -9
  314. package/dist/routes/terminal/live-finish.d.ts +1 -2
  315. package/dist/routes/terminal/live-finish.js +21 -20
  316. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  317. package/dist/routes/terminal/live-sandbox.js +20 -20
  318. package/dist/routes/terminal/participant-text.d.ts +23 -0
  319. package/dist/routes/terminal/participant-text.js +165 -0
  320. package/dist/routes/terminal/plan.d.ts +2 -6
  321. package/dist/routes/terminal/plan.js +13 -9
  322. package/dist/routes/terminal/recorder.d.ts +6 -1
  323. package/dist/routes/terminal/recorder.js +12 -4
  324. package/dist/routes/terminal/result.js +4 -4
  325. package/dist/routes/terminal/route.js +26 -26
  326. package/dist/routes/terminal/runtime.d.ts +3 -2
  327. package/dist/routes/terminal/runtime.js +3 -3
  328. package/dist/routes/terminal/sandbox.d.ts +3 -3
  329. package/dist/routes/terminal/sandbox.js +9 -9
  330. package/dist/routes/terminal/session.js +16 -14
  331. package/dist/routes/terminal/token-usage.js +5 -5
  332. package/dist/routes/terminal/trace.d.ts +5 -8
  333. package/dist/routes/terminal/trace.js +9 -64
  334. package/dist/routes/terminal/types.d.ts +85 -93
  335. package/dist/routes/terminal/types.js +9 -4
  336. package/dist/run/active-runs.d.ts +13 -0
  337. package/dist/run/active-runs.js +12 -0
  338. package/dist/run/bundle-shape.d.ts +2 -1
  339. package/dist/run/bundle-shape.js +4 -4
  340. package/dist/run/bundle.d.ts +63 -56
  341. package/dist/run/bundle.js +9 -8
  342. package/dist/run/cost-summary.js +3 -2
  343. package/dist/run/costs.d.ts +6 -6
  344. package/dist/run/costs.js +10 -10
  345. package/dist/run/detail.d.ts +5 -5
  346. package/dist/run/detail.js +6 -6
  347. package/dist/run/dry-run.js +5 -12
  348. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  349. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  350. package/dist/run/feedback-shape.js +1 -1
  351. package/dist/run/judge.d.ts +16 -4
  352. package/dist/run/judge.js +24 -7
  353. package/dist/run/locate.d.ts +2 -0
  354. package/dist/run/locate.js +3 -1
  355. package/dist/run/outcomes.d.ts +3 -3
  356. package/dist/run/outcomes.js +3 -3
  357. package/dist/run/participant-records.d.ts +2 -2
  358. package/dist/run/participant-records.js +2 -2
  359. package/dist/run/paths.js +1 -1
  360. package/dist/run/pricing.d.ts +19 -9
  361. package/dist/run/pricing.js +30 -18
  362. package/dist/run/projection.d.ts +13 -13
  363. package/dist/run/projection.js +8 -8
  364. package/dist/run/reclaim.d.ts +6 -0
  365. package/dist/run/reclaim.js +13 -3
  366. package/dist/run/results.d.ts +1 -1
  367. package/dist/run/run-index.d.ts +1 -1
  368. package/dist/run/run-index.js +11 -11
  369. package/dist/run/run.d.ts +4 -2
  370. package/dist/run/run.js +9 -5
  371. package/dist/run/sandbox-receipts.d.ts +4 -4
  372. package/dist/run/sandbox-receipts.js +4 -4
  373. package/dist/run/shared-world-evidence.d.ts +47 -47
  374. package/dist/run/shared-world-shape.d.ts +3 -3
  375. package/dist/run/shared-world-shape.js +11 -11
  376. package/dist/run/stats.d.ts +5 -5
  377. package/dist/run/stats.js +8 -8
  378. package/dist/run/status.d.ts +16 -6
  379. package/dist/run/status.js +31 -8
  380. package/dist/run/streams.d.ts +26 -19
  381. package/dist/run/terminal-contract.d.ts +5 -5
  382. package/dist/run/terminal-contract.js +4 -4
  383. package/dist/run/transient-comms-secrets.d.ts +5 -0
  384. package/dist/run/transient-comms-secrets.js +12 -0
  385. package/dist/run-lab.d.ts +36 -34
  386. package/dist/run-lab.js +41 -37
  387. package/dist/subject/desktop-cli.d.ts +1 -1
  388. package/dist/subject/desktop-cli.js +1 -1
  389. package/dist/subject/local-tree-archive.d.ts +1 -1
  390. package/dist/subject/local-tree-archive.js +4 -4
  391. package/dist/subject/local-tree.d.ts +2 -2
  392. package/dist/subject/local-tree.js +1 -1
  393. package/dist/subject/node-bootstrap.d.ts +1 -1
  394. package/dist/subject/node-bootstrap.js +4 -4
  395. package/dist/subject/runtime.js +5 -5
  396. package/dist/subject/serve.js +1 -1
  397. package/dist/subject/steps.d.ts +4 -4
  398. package/dist/subject/steps.js +5 -5
  399. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  400. package/dist/substrates/e2b/cdp-probe.js +1 -1
  401. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  402. package/dist/substrates/e2b/desktop-browser.js +4 -4
  403. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  404. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  405. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  406. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  407. package/dist/substrates/e2b/desktop-media.js +2 -2
  408. package/dist/substrates/e2b/sandbox.js +1 -1
  409. package/dist/substrates/e2b/sdk.js +2 -2
  410. package/dist/substrates/local/runtime-host.d.ts +2 -0
  411. package/dist/substrates/local/runtime-host.js +6 -0
  412. package/dist/tui/actions.d.ts +7 -5
  413. package/dist/tui/actions.js +18 -9
  414. package/dist/tui-app.js +42 -42
  415. package/dist/verify/actor.d.ts +10 -10
  416. package/dist/verify/actor.js +15 -15
  417. package/dist/verify/artifacts.d.ts +1 -1
  418. package/dist/verify/artifacts.js +3 -3
  419. package/dist/verify/costs.d.ts +2 -2
  420. package/dist/verify/costs.js +2 -2
  421. package/dist/verify/liveness.d.ts +1 -1
  422. package/dist/verify/liveness.js +4 -1
  423. package/dist/verify/rerun.d.ts +1 -1
  424. package/dist/verify/rerun.js +1 -1
  425. package/dist/verify/shared-world.js +2 -2
  426. package/dist/verify/verify.js +6 -6
  427. package/docs/README.md +1 -1
  428. package/docs/architecture/actor-contract.md +60 -22
  429. package/docs/architecture/desktop-sessions.md +9 -9
  430. package/docs/architecture/external-public-shared-world.md +5 -0
  431. package/docs/architecture/observer.md +4 -4
  432. package/docs/architecture/restricted-codex-analysis.md +36 -2
  433. package/docs/architecture/state-driven-executor.md +4 -5
  434. package/docs/architecture/task-protocol-support.md +3 -5
  435. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  436. package/docs/contracts/run-bundle.md +10 -8
  437. package/docs/contracts/schemas.md +109 -53
  438. package/docs/contracts/study-analysis.md +24 -0
  439. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  440. package/docs/product/automatic-analysis.md +1 -0
  441. package/docs/ramp/README.md +2 -1
  442. package/package.json +4 -4
  443. package/skills/humanish/SKILL.md +3 -2
  444. package/skills/humanish/agents/openai.yaml +1 -1
  445. package/dist/deprecated.d.ts +0 -90
  446. package/dist/deprecated.js +0 -106
  447. package/dist/lab/bag-overrides.d.ts +0 -18
  448. package/dist/lab/bag-overrides.js +0 -121
  449. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  450. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  451. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  452. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  453. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -1,5 +1,6 @@
1
- import { type RestrictedCodexResult, type RestrictedCodexUsage } from "./restricted-policy.js";
1
+ import { type RestrictedCodexAnalysisErrorCode, type RestrictedCodexResult, type RestrictedCodexUsage } from "./restricted-policy.js";
2
2
  import { type RestrictedCodexDeadline, type RestrictedCodexTransport } from "./restricted-transport.js";
3
+ import { type NotificationPolicy } from "./restricted-notifications.js";
3
4
  /** What a turn reads from and reports to its session. */
4
5
  export interface RestrictedCodexTurnContext {
5
6
  readonly deadline: RestrictedCodexDeadline;
@@ -23,11 +24,23 @@ export interface RestrictedCodexTurnContext {
23
24
  reportUsage(usage: RestrictedCodexUsage | undefined, inference: RestrictedCodexUsage[] | undefined): void;
24
25
  /** The turn the session interrupts if it closes now. */
25
26
  turnStarted(turnId: string): void;
27
+ /** The item policy every notification's item passes, whatever its method. */
28
+ readonly policy: NotificationPolicy;
29
+ /** The session's handler for notifications that arrive before this turn is dispatched. */
30
+ idle(method: string, params: Record<string, unknown>): void;
31
+ /** Counts a notification method this humanish does not know that carried no item. */
32
+ recordUnknown(method: string): void;
33
+ /**
34
+ * A policy refusal: stops this request with `code`, and the session records it when the
35
+ * request already stopped for another reason, such as a close.
36
+ */
37
+ refuse(code: RestrictedCodexAnalysisErrorCode): void;
26
38
  }
27
39
  /**
28
- * Drain: every notification and tool request of one turn. Nothing is handled before `dispatched`;
29
- * events that arrive before turn/start's reply wait until acknowledge() and are then checked in
30
- * order. `finished` resolves only with a completed, validated final answer.
40
+ * Drain: every notification and tool request of one turn. Before `dispatched`, notifications go
41
+ * to the session's idle handler; events that arrive after dispatch but before turn/start's reply
42
+ * pass the item policy at once, then wait until acknowledge() and are checked in order.
43
+ * `finished` resolves only with a completed, validated final answer.
31
44
  */
32
45
  export declare class RestrictedCodexTurn {
33
46
  private readonly context;
@@ -53,6 +66,8 @@ export declare class RestrictedCodexTurn {
53
66
  acknowledge(returnedTurnId: unknown): void;
54
67
  readonly onNotification: RestrictedCodexTransport["onNotification"];
55
68
  readonly onRequest: NonNullable<RestrictedCodexTransport["onRequest"]>;
69
+ /** Refuses a tool request: the session records the refusal, and the transport answers it. */
70
+ private refuseRequest;
56
71
  readonly onRequestComplete: () => void;
57
72
  private handleTurnEvent;
58
73
  private recordUsage;
@@ -1,17 +1,11 @@
1
1
  // One restricted Codex request's turn: the notifications and tool requests the app-server sends
2
2
  // while the turn runs. Each is checked against the tool policy, the turn's identity and the output
3
- // limits, and any violation stops the request's deadline with a refusal code.
3
+ // limits, and any violation stops the request's deadline with a refusal code. A policy violation
4
+ // goes through the session, which records it when the request can no longer report it.
4
5
  import { CODEX_MAX_OUTPUT_BYTES, CODEX_MAX_REQUEST_BYTES, codexRecord, restrictedCodexUsage, toolPolicyViolation, } from "./restricted-policy.js";
5
6
  import { RestrictedCodexStop, } from "./restricted-transport.js";
7
+ import { ANALYST_ITEM_TYPES, ANALYST_RAW_ITEM_TYPES, KNOWN_CODEX_NOTIFICATIONS, PARTICIPANT_ITEM_TYPES, PARTICIPANT_RAW_ITEM_TYPES, itemPolicyOf, } from "./restricted-notifications.js";
6
8
  const rawCompactionTypes = ["compaction", "compaction_summary", "context_compaction"];
7
- const analystRawItemTypes = ["message", "reasoning", ...rawCompactionTypes];
8
- const participantRawItemTypes = [
9
- ...analystRawItemTypes,
10
- "custom_tool_call",
11
- "custom_tool_call_output",
12
- "function_call",
13
- "function_call_output",
14
- ];
15
9
  function hasScopedIdentity(method, params, threadId, turnId) {
16
10
  if (method === "turn/started" || method === "turn/completed") {
17
11
  const id = codexRecord(params.turn).id;
@@ -28,8 +22,10 @@ function hasScopedIdentity(method, params, threadId, turnId) {
28
22
  typeof params.turnId === "string" &&
29
23
  params.turnId.length > 0 &&
30
24
  (turnId === undefined || params.turnId === turnId));
25
+ // Before the turn's id is known, an event that names a turn waits in the early buffer, and
26
+ // handleTurnEvent checks it again against the acknowledged id.
31
27
  return ((params.threadId === undefined || params.threadId === threadId) &&
32
- (params.turnId === undefined || params.turnId === turnId));
28
+ (params.turnId === undefined || turnId === undefined || params.turnId === turnId));
33
29
  }
34
30
  function usageDelta(total, baseline) {
35
31
  const delta = {
@@ -44,9 +40,10 @@ function usageDelta(total, baseline) {
44
40
  : null;
45
41
  }
46
42
  /**
47
- * Drain: every notification and tool request of one turn. Nothing is handled before `dispatched`;
48
- * events that arrive before turn/start's reply wait until acknowledge() and are then checked in
49
- * order. `finished` resolves only with a completed, validated final answer.
43
+ * Drain: every notification and tool request of one turn. Before `dispatched`, notifications go
44
+ * to the session's idle handler; events that arrive after dispatch but before turn/start's reply
45
+ * pass the item policy at once, then wait until acknowledge() and are checked in order.
46
+ * `finished` resolves only with a completed, validated final answer.
50
47
  */
51
48
  export class RestrictedCodexTurn {
52
49
  context;
@@ -70,7 +67,9 @@ export class RestrictedCodexTurn {
70
67
  constructor(context) {
71
68
  this.context = context;
72
69
  this.inferenceUsage = context.participant ? [] : null;
73
- this.allowedRawItemTypes = context.participant ? participantRawItemTypes : analystRawItemTypes;
70
+ this.allowedRawItemTypes = context.participant
71
+ ? PARTICIPANT_RAW_ITEM_TYPES
72
+ : ANALYST_RAW_ITEM_TYPES;
74
73
  this.finished = new Promise((resolve) => {
75
74
  this.resolveFinished = resolve;
76
75
  });
@@ -94,8 +93,21 @@ export class RestrictedCodexTurn {
94
93
  }
95
94
  onNotification = (method, params) => {
96
95
  const { deadline } = this.context;
97
- if (!this.dispatched)
96
+ if (!this.dispatched) {
97
+ this.context.idle(method, params);
98
98
  return;
99
+ }
100
+ // The single tool-policy check, first: an event that also fails the identity or delta checks
101
+ // below still has its items recorded. Tool requests must fail even if the turn-start
102
+ // acknowledgment is lost, and every event reaches handleTurnEvent only from here, directly or
103
+ // through the early buffer, so no event skips it. Every item is checked, whatever the method
104
+ // that carries it and wherever the schema nests it.
105
+ const items = itemPolicyOf(method, params, this.context.policy);
106
+ if (toolPolicyViolation(method, codexRecord(params.item), this.allowedRawItemTypes) ||
107
+ items === "violation") {
108
+ this.context.refuse("codex_tool_call");
109
+ return;
110
+ }
99
111
  if (!hasScopedIdentity(method, params, this.context.threadId(), this.turnId ?? this.earlyTurnId)) {
100
112
  deadline.stop("codex_protocol_error");
101
113
  return;
@@ -111,13 +123,8 @@ export class RestrictedCodexTurn {
111
123
  return;
112
124
  }
113
125
  }
114
- // The single tool-policy check. Tool requests must fail even if the turn-start
115
- // acknowledgment is lost, and every event reaches handleTurnEvent only from here, directly
116
- // or through the early buffer, so no event skips it.
117
- if (toolPolicyViolation(method, codexRecord(params.item), this.allowedRawItemTypes)) {
118
- deadline.stop("codex_tool_call");
119
- return;
120
- }
126
+ if (items === "none" && !KNOWN_CODEX_NOTIFICATIONS.has(method))
127
+ this.context.recordUnknown(method);
121
128
  if (method === "turn/started") {
122
129
  const value = codexRecord(params.turn).id;
123
130
  if (typeof value !== "string" ||
@@ -137,7 +144,10 @@ export class RestrictedCodexTurn {
137
144
  onRequest = async (method, params) => {
138
145
  const { deadline, participant, toolCallIds } = this.context;
139
146
  const callId = params.callId;
140
- if (!participant ||
147
+ // A request before turn/start is sent, or after the turn completed, is outside the turn.
148
+ if (!this.dispatched ||
149
+ this.completed ||
150
+ !participant ||
141
151
  method !== "item/tool/call" ||
142
152
  params.threadId !== this.context.threadId() ||
143
153
  typeof params.turnId !== "string" ||
@@ -150,13 +160,13 @@ export class RestrictedCodexTurn {
150
160
  callId.length > 200 ||
151
161
  toolCallIds.has(callId) ||
152
162
  this.toolRequestPending)
153
- throw new RestrictedCodexStop("codex_tool_call");
163
+ this.refuseRequest();
154
164
  // Mark the request outstanding before waiting for a same-chunk turn/start
155
165
  // acknowledgment, so an early completion can never be accepted.
156
166
  this.toolRequestPending = true;
157
167
  const activeTurnId = this.turnId ?? this.earlyTurnId ?? (await deadline.wait(this.turnReady));
158
168
  if (params.turnId !== activeTurnId)
159
- throw new RestrictedCodexStop("codex_tool_call");
169
+ this.refuseRequest();
160
170
  toolCallIds.add(callId);
161
171
  deadline.pause();
162
172
  const text = await deadline.wait(this.context.tool().call(params.arguments));
@@ -170,6 +180,11 @@ export class RestrictedCodexTurn {
170
180
  }
171
181
  return { success: true, contentItems: [{ type: "inputText", text }] };
172
182
  };
183
+ /** Refuses a tool request: the session records the refusal, and the transport answers it. */
184
+ refuseRequest() {
185
+ this.context.refuse("codex_tool_call");
186
+ throw new RestrictedCodexStop("codex_tool_call");
187
+ }
173
188
  onRequestComplete = () => {
174
189
  this.toolRequestPending = false;
175
190
  };
@@ -220,11 +235,9 @@ export class RestrictedCodexTurn {
220
235
  /** The item allowlist, the participant's one dynamic tool and the final answer's shape. */
221
236
  admitsItem(method, item) {
222
237
  const { deadline, participant } = this.context;
223
- const allowedItems = participant
224
- ? ["userMessage", "agentMessage", "reasoning", "contextCompaction", "dynamicToolCall"]
225
- : ["userMessage", "agentMessage", "reasoning", "contextCompaction"];
238
+ const allowedItems = participant ? PARTICIPANT_ITEM_TYPES : ANALYST_ITEM_TYPES;
226
239
  if (!allowedItems.includes(String(item.type))) {
227
- deadline.stop("codex_tool_call");
240
+ this.context.refuse("codex_tool_call");
228
241
  return false;
229
242
  }
230
243
  if (item.type === "dynamicToolCall" &&
@@ -232,7 +245,7 @@ export class RestrictedCodexTurn {
232
245
  item.namespace !== null ||
233
246
  (method === "item/started" && item.status !== "inProgress") ||
234
247
  (method === "item/completed" && (item.status !== "completed" || item.success !== true)))) {
235
- deadline.stop("codex_tool_call");
248
+ this.context.refuse("codex_tool_call");
236
249
  return false;
237
250
  }
238
251
  if (item.type === "agentMessage" &&
@@ -6,7 +6,7 @@ import { type RedactionHooks } from "../../evidence/redaction.js";
6
6
  import type { DwellWindow, StopWhen } from "../stop-conditions.js";
7
7
  import type { LabTask } from "../../lab/tasks.js";
8
8
  export interface CuaActorSessionOptions {
9
- /** The composed mission (persona + scenario/lane instruction) handed to the model. */
9
+ /** The composed mission (persona + scenario/participant instruction) handed to the model. */
10
10
  instructions: string;
11
11
  /** Provenance of the persona this actor embodies (id + applied traits + prompt digest). */
12
12
  persona: ActorPersonaRef;
@@ -18,8 +18,8 @@ export async function runCuaActorSession(options) {
18
18
  }
19
19
  const strictSpend = options.requireReportedUsageForSpendCap === true &&
20
20
  (options.maxUsd !== undefined || options.overRunBudget !== undefined);
21
- const provider = options.provider ?? buildProvider(options.openai, strictSpend);
22
- const executor = options.executor ?? buildExecutor(options.desktop, options.executorOptions);
21
+ const provider = options.provider ?? defaultProvider(options.openai, strictSpend);
22
+ const executor = options.executor ?? defaultExecutor(options.desktop, options.executorOptions);
23
23
  const loopOptions = {
24
24
  instructions: options.instructions,
25
25
  provider,
@@ -61,7 +61,7 @@ export async function runCuaActorSession(options) {
61
61
  }
62
62
  return result;
63
63
  }
64
- function buildProvider(openai, strictSpend = false) {
64
+ function defaultProvider(openai, strictSpend = false) {
65
65
  if (!openai) {
66
66
  throw new Error("runCuaActorSession requires either `provider` (injected) or `openai` provider options.");
67
67
  }
@@ -70,7 +70,7 @@ function buildProvider(openai, strictSpend = false) {
70
70
  ...(strictSpend ? { singleDispatch: true } : {}),
71
71
  });
72
72
  }
73
- function buildExecutor(desktop, executorOptions) {
73
+ function defaultExecutor(desktop, executorOptions) {
74
74
  if (!desktop) {
75
75
  throw new Error("runCuaActorSession requires either `executor` (injected) or `desktop` to build one.");
76
76
  }
@@ -130,7 +130,7 @@ export function advanceBackstop(previous, turn, limits) {
130
130
  // CORROBORATION (#383). A stale frame alone is NOT evidence of a stuck agent. The frame hash is
131
131
  // a coarse whole-screen measure, and on a light-themed web app it can miss a renamed row, a new
132
132
  // list item, or an opened panel — a measured run had 9 visibly different consecutive frames hash
133
- // identically while the agent was a foreign key away from finishing. Ending a lane on that
133
+ // identically while the agent was a foreign key away from finishing. Ending a participant on that
134
134
  // signal alone recorded working sessions as `gave_up`, capping every browser run at roughly
135
135
  // noProgressSteps turns and writing harness artifacts into evidence as actor behavior.
136
136
  //
@@ -28,7 +28,7 @@ export declare function declaredOutcomeOf(turn: CuaTurn): ParticipantDeclaredOut
28
28
  /**
29
29
  * The participant reported a natural endpoint. "not_reached" is a participant who stopped without
30
30
  * finishing: gave_up, which tallies as abandoned. "blocked" keeps goal_satisfied here (the actor
31
- * did stop on purpose) and the lane's credibility read turns it into a blocked participant, the
31
+ * did stop on purpose) and the route's credibility read turns it into a blocked participant, the
32
32
  * same path a narrated blocker takes.
33
33
  */
34
34
  export declare function participantEnded(turn: CuaTurn, declaredOutcome: ParticipantDeclaredOutcome | undefined, redactNarration: (text: string) => string): Stop;
@@ -47,7 +47,7 @@ export declare function timeLimit(session: LoopSession): Stop;
47
47
  export declare function spendLimit(session: LoopSession, estimate: number, maxUsd: number): Stop;
48
48
  export declare const nonFiniteEstimate: Stop;
49
49
  /** A study-level stop is a recruiting decision hitting its limit, not this participant's runaway. */
50
- export declare function studySpendLimit(reason: string): Stop;
50
+ export declare function runSpendLimit(reason: string): Stop;
51
51
  export declare const accountBilledCaps: Stop;
52
52
  export declare const adapterLimit: Stop;
53
53
  export declare const usageUnreported: Stop;
@@ -32,7 +32,7 @@ export function declaredOutcomeOf(turn) {
32
32
  /**
33
33
  * The participant reported a natural endpoint. "not_reached" is a participant who stopped without
34
34
  * finishing: gave_up, which tallies as abandoned. "blocked" keeps goal_satisfied here (the actor
35
- * did stop on purpose) and the lane's credibility read turns it into a blocked participant, the
35
+ * did stop on purpose) and the route's credibility read turns it into a blocked participant, the
36
36
  * same path a narrated blocker takes.
37
37
  */
38
38
  export function participantEnded(turn, declaredOutcome, redactNarration) {
@@ -98,7 +98,7 @@ export const nonFiniteEstimate = {
98
98
  reason: "the injected estimateTurnCostUsd returned a non-finite estimate while execution.caps.maxUsd is set; the estimator receives one ActorTokenUsage object. Failing closed instead of running uncapped.",
99
99
  };
100
100
  /** A study-level stop is a recruiting decision hitting its limit, not this participant's runaway. */
101
- export function studySpendLimit(reason) {
101
+ export function runSpendLimit(reason) {
102
102
  return { completionReason: "budget_reached", reason, stopCause: "study_spend_limit" };
103
103
  }
104
104
  // A host-authenticated provider may learn its account billing class during startup. Never price
@@ -8,7 +8,7 @@ export declare class LostRequestRefused extends Error {
8
8
  }
9
9
  /**
10
10
  * The spend caps, checked before the next provider request so a model stuck retrying cannot keep
11
- * spending. The lane cap stops the session once the running estimate crosses maxUsd; a null
11
+ * spending. The per-participant cap stops the session once the running estimate crosses maxUsd; a null
12
12
  * estimate cannot trip it, because preflight guaranteed a rate. The study budget (#299) is checked
13
13
  * next.
14
14
  */
@@ -1,6 +1,6 @@
1
1
  import * as stops from "./ending.js";
2
2
  import { notice } from "./trace.js";
3
- // The spend guards. The lane cap (maxUsd) and the study budget (overRunBudget) are priced from
3
+ // The spend guards. The per-participant cap (maxUsd) and the study budget (overRunBudget) are priced from
4
4
  // the usage each reply reports, plus a worst-case charge booked for each request lost without a
5
5
  // reply. A request whose cost is unknown and unbounded stops a capped session before the next one.
6
6
  /** Thrown through the provider when a lost attempt may not be sent again; carries the stop. */
@@ -13,7 +13,7 @@ export class LostRequestRefused extends Error {
13
13
  }
14
14
  /**
15
15
  * The spend caps, checked before the next provider request so a model stuck retrying cannot keep
16
- * spending. The lane cap stops the session once the running estimate crosses maxUsd; a null
16
+ * spending. The per-participant cap stops the session once the running estimate crosses maxUsd; a null
17
17
  * estimate cannot trip it, because preflight guaranteed a rate. The study budget (#299) is checked
18
18
  * next.
19
19
  */
@@ -29,7 +29,7 @@ export function spendStop(session) {
29
29
  if (overRunBudget) {
30
30
  const runStop = overRunBudget(session.usage.forCap());
31
31
  if (runStop !== null)
32
- return stops.studySpendLimit(runStop);
32
+ return stops.runSpendLimit(runStop);
33
33
  }
34
34
  return undefined;
35
35
  }
@@ -37,7 +37,7 @@ export class TraceRecorder {
37
37
  export function statusForCompletionReason(reason) {
38
38
  switch (reason) {
39
39
  case "goal_satisfied":
40
- case "turn_completed": // turn_completed is a Codex-lane reason; this loop emits goal_satisfied
40
+ case "turn_completed": // turn_completed is a Codex reason; this loop emits goal_satisfied
41
41
  return "passed";
42
42
  // A session that ran out of time or budget did not reach its goal, whatever it achieved along
43
43
  // the way. Calling that `passed` is how a truncated study came to be reported as a green one —
@@ -56,7 +56,7 @@ export function statusForCompletionReason(reason) {
56
56
  return "abandoned";
57
57
  // Only the harness failing is a harness failure.
58
58
  case "actor_error":
59
- case "step_failed": // step_failed is the scripted-browser lane's reason; this loop never emits it
59
+ case "step_failed": // step_failed is the scripted-browser route's reason; this loop never emits it
60
60
  case "harness_error":
61
61
  return "failed";
62
62
  }
@@ -229,7 +229,7 @@ export interface CuaProvider {
229
229
  nextTurn(req: CuaTurnRequest, signal: AbortSignal, spend?: CuaSpendGate): Promise<CuaTurn>;
230
230
  /** Optional read-only closing report. Implementations must disable tools and make no retries. */
231
231
  debrief?: ((req: CuaTurnRequest, signal: AbortSignal) => Promise<CuaTurn>) | undefined;
232
- /** Release lane-owned model resources. Idempotent; reject if cleanup is unconfirmed. */
232
+ /** Release the participant's model resources. Idempotent; reject if cleanup is unconfirmed. */
233
233
  close?(): Promise<void>;
234
234
  }
235
235
  /** The desktop side of the loop. */
@@ -261,7 +261,7 @@ export interface CuaLoopOptions {
261
261
  /**
262
262
  * Per-attempt bound on the provider call (#469), so a hung request is told apart from a
263
263
  * participant still thinking. A stalled turn is retried once with a notice; a second stall ends
264
- * the lane as harness_error.
264
+ * the participant as harness_error.
265
265
  */
266
266
  turnTimeoutMs?: number;
267
267
  /**
@@ -308,7 +308,7 @@ export interface CuaLoopOptions {
308
308
  writeScreenshot?: (name: string, bytes: Buffer) => Promise<string>;
309
309
  /**
310
310
  * Deterministic harness-owned success guards. Evaluated after the initial observation and after
311
- * every post-action observation, before another model turn is requested. This keeps a lane from
311
+ * every post-action observation, before another model turn is requested. This keeps a participant from
312
312
  * wandering after the product already reached an app-visible endpoint.
313
313
  */
314
314
  stopWhen?: StopWhen;
@@ -346,8 +346,8 @@ export interface CuaLoopOptions {
346
346
  */
347
347
  estimateTurnCostUsd?: (usage: ActorTokenUsage) => number | null;
348
348
  /**
349
- * RUN-LEVEL spend guard (#299): called with this lane's running usage each turn, at the same
350
- * point the per-lane cap is checked. Returns a human-readable reason when the STUDY's shared
349
+ * RUN-LEVEL spend guard (#299): called with this participant's running usage each turn, at the same
350
+ * point the per-participant cap is checked. Returns a human-readable reason when the STUDY's shared
351
351
  * budget is exhausted, else null. On a non-null return the loop stops with `budget_reached`
352
352
  * regardless of material progress — a study-level stop is a recruiting decision hitting its
353
353
  * limit, not this participant's runaway, so it never reads as `gave_up`.
@@ -368,6 +368,9 @@ export interface CuaLoopOptions {
368
368
  *
369
369
  * Built-in caller: the external-public shared-world handoff (src/routes/shared-world/handoff.ts)
370
370
  * latches the host participant's lobby URL and checks that each follower reached the same lobby.
371
+ *
372
+ * @deprecated Wrap the executor's `observe` and read `url` from each observation it returns. The
373
+ * next minor removes this option.
371
374
  */
372
375
  onObservedUrl?: (url: string | undefined) => void;
373
376
  /**
@@ -378,6 +381,9 @@ export interface CuaLoopOptions {
378
381
  *
379
382
  * Built-in caller: the external-public handoff scans the host's narration for the lobby code,
380
383
  * because the E2B desktop's CDP URL read behind onObservedUrl is unreliable.
384
+ *
385
+ * @deprecated Wrap the provider's `nextTurn` and read `reasoning` and `message` from each turn it
386
+ * returns. The next minor removes this option.
381
387
  */
382
388
  onMessage?: (text: string) => void;
383
389
  /**
@@ -387,6 +393,9 @@ export interface CuaLoopOptions {
387
393
  *
388
394
  * Built-in caller: the external-public handoff reads the lobby code off each participant's own
389
395
  * frame until that participant has one: the host's latch, or a follower's convergence observation.
396
+ *
397
+ * @deprecated Wrap the executor's `observe` and read `screenshot` from each observation it
398
+ * returns. The next minor removes this option.
390
399
  */
391
400
  onScreenshot?: (frame: Buffer) => void;
392
401
  /**
@@ -187,11 +187,11 @@ function stopBeforeActing(session, turn, turnNumber) {
187
187
  return stops.accountBilledCaps;
188
188
  if (turn.interruption !== undefined) {
189
189
  // Preserve usage and partial narration of an interrupted response. Its usage still counts
190
- // toward the study budget; when that exhausts it, sibling lanes stop, so this trace says why.
191
- const studyStop = overRunBudget?.(session.usage.forCap());
190
+ // toward the study budget; when that exhausts it, sibling participants stop, so this trace says why.
191
+ const runBudgetStop = overRunBudget?.(session.usage.forCap());
192
192
  recordNarration(session, turn, turnNumber, "interrupted");
193
- if (studyStop != null) {
194
- session.trace.record("notice", () => notice("warn", "study budget reached during an interrupted response", studyStop));
193
+ if (runBudgetStop != null) {
194
+ session.trace.record("notice", () => notice("warn", "study budget reached during an interrupted response", runBudgetStop));
195
195
  }
196
196
  return stops.providerInterrupted(turn.interruption);
197
197
  }
@@ -46,7 +46,7 @@ export declare const RETRY_AFTER_CAP_MS = 60000;
46
46
  * Parse a Retry-After header (delay-seconds or an HTTP-date) into milliseconds from `now`;
47
47
  * undefined when absent or unreadable. OpenAI's 2026-09-02 change added `429 slow_down` and
48
48
  * `503 server_is_overloaded`, both of which may carry it; a fixed 200/400/800 ms backoff against
49
- * a 20 s hint burns every retry inside the hint and ends the lane for nothing.
49
+ * a 20 s hint burns every retry inside the hint and ends the participant's session for nothing.
50
50
  */
51
51
  export declare function retryAfterMs(value: string | null | undefined, now: number): number | undefined;
52
52
  /**
@@ -93,7 +93,7 @@ export const RETRY_AFTER_CAP_MS = 60_000;
93
93
  * Parse a Retry-After header (delay-seconds or an HTTP-date) into milliseconds from `now`;
94
94
  * undefined when absent or unreadable. OpenAI's 2026-09-02 change added `429 slow_down` and
95
95
  * `503 server_is_overloaded`, both of which may carry it; a fixed 200/400/800 ms backoff against
96
- * a 20 s hint burns every retry inside the hint and ends the lane for nothing.
96
+ * a 20 s hint burns every retry inside the hint and ends the participant's session for nothing.
97
97
  */
98
98
  export function retryAfterMs(value, now) {
99
99
  if (value === null || value === undefined)
@@ -109,7 +109,7 @@ export function retryAfterMs(value, now) {
109
109
  return Math.max(0, at - now);
110
110
  }
111
111
  /**
112
- * The provider error codes a lane's reason may name. Read from a non-ok body, which is never
112
+ * The provider error codes a participant's reason may name. Read from a non-ok body, which is never
113
113
  * kept or logged (it can echo the input); only a code on this list crosses over.
114
114
  */
115
115
  const NAMED_PROVIDER_ERROR_CODES = [
@@ -24,7 +24,7 @@ export type ActorStatus = (typeof ACTOR_STATUSES)[number];
24
24
  /**
25
25
  * What the PARTICIPANT said happened, in a field rather than a paragraph (#570). Providers whose
26
26
  * reply is schema-constrained (the local-agent routes) fill it on their final turn; a free-text
27
- * provider leaves it absent and the lane falls back to reading the closing message. `reached`:
27
+ * provider leaves it absent and the route falls back to reading the closing message. `reached`:
28
28
  * the task is finished. `blocked`: something in the app stopped the participant. `not_reached`:
29
29
  * the participant stopped for another reason (gave up, ran out of ideas).
30
30
  */
@@ -193,7 +193,9 @@ export interface ActorRuntimeProvenance {
193
193
  observedVersion?: string;
194
194
  versionStatus: "unobserved" | "verified" | "failed";
195
195
  requestedModel?: string;
196
- modelStatus: "declared" | "runtime_default_unobserved";
196
+ /** Where requestedModel came from. Bundles written before humanish always passed a model record
197
+ * `runtime_default_unobserved`, with no requestedModel. */
198
+ modelStatus: "declared" | "humanish_default" | "runtime_default_unobserved";
197
199
  requestedReasoningEffort?: string;
198
200
  /** Codex turn.completed aggregates requests; it cannot establish per-request pricing tiers. */
199
201
  usageGranularity: "runtime_turn";
@@ -231,7 +233,7 @@ export interface ActorTrace {
231
233
  /**
232
234
  * ADDITIVE + OPTIONAL record of HOW the model was asked to run (humanish.model-settings.v1,
233
235
  * #497). `ids.model` says which model; this says the reasoning effort the request actually
234
- * carried. Present on lanes whose provider declares settings; absent everywhere else and on
236
+ * carried. Present on traces whose provider declares settings; absent everywhere else and on
235
237
  * every pre-existing bundle, and its absence is tolerated by verify.
236
238
  *
237
239
  * It exists because effort was a silent constant: unreachable from a lab, so every run took the
@@ -248,7 +250,7 @@ export interface ActorTrace {
248
250
  * ADDITIVE + OPTIONAL affordance record (humanish.affordance-use.v1, #369): which KIND of route
249
251
  * this actor took — pointer, keyboard, url-navigation, script-execution, devtools,
250
252
  * browser-internal, observation — as per-class counts over the run's dispatched actions.
251
- * Present on computer-use lanes that dispatched at least one action; absent elsewhere and on
253
+ * Present on computer-use traces that dispatched at least one action; absent elsewhere and on
252
254
  * every pre-existing bundle (its absence is tolerated by verify). The harness records the class
253
255
  * and states NO verdict: whether a class is faithful depends on the population the study
254
256
  * declares, which is product semantics and belongs to the adopter's scorer. See
@@ -266,7 +268,7 @@ export interface ActorTrace {
266
268
  /**
267
269
  * ADDITIVE + OPTIONAL (#570): the outcome the participant declared on its final turn, when its
268
270
  * provider's reply carries the field. Absent on free-text providers and on every older bundle.
269
- * The lane reads this before it reads the closing paragraph; three regex patches in one month
271
+ * The route reads this before it reads the closing paragraph; three regex patches in one month
270
272
  * (#453, #549, #565) each fixed a false refusal and each left the next shape unhandled.
271
273
  */
272
274
  declaredOutcome?: ParticipantDeclaredOutcome;
@@ -287,11 +289,11 @@ export interface ActorTrace {
287
289
  * Known tokenUsage remains usable as a partial total. Absence is not proof of completeness. */
288
290
  interactionUsageIncomplete?: true;
289
291
  /**
290
- * ADDITIVE + OPTIONAL token-derived cost ESTIMATE for this lane (humanish.actor-estimated-cost.v1).
292
+ * ADDITIVE + OPTIONAL token-derived cost ESTIMATE for this trace (humanish.actor-estimated-cost.v1).
291
293
  * Distinct from `tokenUsage.costUsd`, which is RESERVED for a real provider-returned charge: a
292
294
  * bare `costUsd` always means "the provider billed this", while `estimatedCost.estimatedCostUsd`
293
295
  * is a rate-table multiply named honestly as an estimate (invariant 6). Absent on the Codex
294
- * app-server and scripted lanes and on every pre-existing bundle; the terminal lane records a
296
+ * app-server and scripted traces and on every pre-existing bundle; the terminal trace records a
295
297
  * null estimate. Its absence is tolerated by verify (fail-open on display). A `null`
296
298
  * estimatedCostUsd is DECLARED ABSENT (unknown rate / no usage), never 0.
297
299
  */
@@ -18,7 +18,7 @@
18
18
  //
19
19
  // WHERE IT IS SAFE, and this inverts the intuitive reading: the local agent only DECIDES. humanish
20
20
  // executes the action inside the desktop sandbox, so nothing the persona chooses ever runs on the
21
- // operator's machine. The same trick on the TERMINAL lane would be the opposite — it would move
21
+ // operator's machine. The same trick on the TERMINAL route would be the opposite — it would move
22
22
  // code execution out of the sandbox and onto a real disk — which is why this is a computer-use
23
23
  // provider and nothing else. Even so, these are coding agents with their own shell and file tools,
24
24
  // so each one is spawned tool-restricted, in a scratch directory, with a per-turn timeout.
@@ -10,10 +10,10 @@ export interface ScriptedBrowserSessionOptions {
10
10
  urlPolicy?: ScriptedBrowserEvidenceUrlPolicy;
11
11
  /** Parsed + validated by the backend (scenario.ref is consumed there, fail-closed). */
12
12
  journey: BrowserPersonaJourney;
13
- /** ONE session per surface lane. */
13
+ /** ONE session per surface. */
14
14
  surface: BrowserSurface;
15
15
  /** id = actors[0].persona ?? "scripted-journey"; promptDigest = journey.sourceDigest prefix
16
- * (the step manifest IS the "prompt" — no model prompt exists on this lane). */
16
+ * (the step manifest IS the "prompt" — no model prompt exists on this route). */
17
17
  persona: ActorPersonaRef;
18
18
  /** Journey wall-clock budget in ms; the lab route passes execution.timeoutMs or 300_000. */
19
19
  timeoutMs: number;
@@ -1,6 +1,7 @@
1
1
  // Parse a scenario's `browser.steps` into a BrowserPersonaJourney: the actions, text assertions and
2
2
  // expectations the scripted browser runs. The journey is the actor's whole behavior.
3
3
  import path from "node:path";
4
+ import { isRecord } from "../../run/type-guards.js";
4
5
  export function parseBrowserPersonaJourneyFromScenario(args) {
5
6
  if (!isRecord(args.raw)) {
6
7
  return {};
@@ -86,7 +87,16 @@ function parseBrowserPersonaStep(rawStep, index) {
86
87
  const selector = stringValue(source.selector);
87
88
  const pathValue = stringValue(source.path);
88
89
  const value = stringValue(source.value);
90
+ const key = stringValue(source.key);
89
91
  const expectation = browserStepExpectationValue(source.expect ?? source.expectation);
92
+ if (action === "press" && !key) {
93
+ return { failure: `${id} press action requires key (for example Enter).` };
94
+ }
95
+ if (action !== "press" && "key" in source) {
96
+ return {
97
+ failure: `${id} sets key, which only a press step sends. Supported actions: ${SUPPORTED_ACTIONS}.`,
98
+ };
99
+ }
90
100
  if (action === "fill" && !selector) {
91
101
  return { failure: `${id} fill action requires selector.` };
92
102
  }
@@ -105,12 +115,14 @@ function parseBrowserPersonaStep(rawStep, index) {
105
115
  ...(pathValue === undefined ? {} : { path: pathValue }),
106
116
  ...(selector === undefined ? {} : { selector }),
107
117
  ...(value === undefined ? {} : { value }),
118
+ ...(key === undefined ? {} : { key }),
108
119
  },
109
120
  };
110
121
  }
111
122
  function hasInlineBrowserSteps(value) {
112
123
  return Array.isArray(value) && value.some((entry) => isRecord(entry) && isRecord(entry.browser));
113
124
  }
125
+ const SUPPORTED_ACTIONS = "goto, fill, click, press, assertText, waitForText, waitForSelector";
114
126
  function browserPersonaActionValue(value) {
115
127
  if (typeof value !== "string") {
116
128
  return null;
@@ -121,8 +133,10 @@ function browserPersonaActionValue(value) {
121
133
  .replace(/[-_\s]+/g, "");
122
134
  if (normalized === "goto" || normalized === "open" || normalized === "navigate")
123
135
  return "goto";
124
- if (normalized === "click" || normalized === "press")
136
+ if (normalized === "click")
125
137
  return "click";
138
+ if (normalized === "press")
139
+ return "press";
126
140
  if (normalized === "fill" || normalized === "type")
127
141
  return "fill";
128
142
  if (normalized === "asserttext" || normalized === "expecttext")
@@ -152,9 +166,6 @@ function browserStepExpectationValue(value) {
152
166
  };
153
167
  return Object.keys(expectation).length === 0 ? undefined : expectation;
154
168
  }
155
- function isRecord(value) {
156
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
157
- }
158
169
  function stringValue(value) {
159
170
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
160
171
  }
@@ -52,6 +52,24 @@ export async function executeBrowserPersonaStep(args) {
52
52
  await target.click({ timeout: stepTimeoutMs });
53
53
  await args.page.waitForTimeout(300);
54
54
  }
55
+ else if (args.step.action === "press") {
56
+ if (!args.step.key) {
57
+ throw new Error(`${args.step.id} press step is missing key`);
58
+ }
59
+ // With a selector, Playwright focuses that element first; without one, the key goes to
60
+ // whatever has focus, such as the input a fill step just typed into.
61
+ if (args.step.selector) {
62
+ const target = args.page.locator(args.step.selector).first();
63
+ if ((await target.count()) === 0) {
64
+ throw new Error(`${args.step.id} press step found no target`);
65
+ }
66
+ await target.press(args.step.key, { timeout: stepTimeoutMs });
67
+ }
68
+ else {
69
+ await args.page.keyboard.press(args.step.key);
70
+ }
71
+ await args.page.waitForTimeout(300);
72
+ }
55
73
  else if (args.step.action === "assertText" || args.step.action === "waitForText") {
56
74
  const expectedText = args.step.expectation?.text ?? args.step.value;
57
75
  if (!expectedText) {