humanish 0.106.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/AGENTS.md +4 -2
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +24 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -6
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +31 -4
  16. package/dist/actors/codex/qualified-versions.js +51 -6
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +10 -8
  45. package/dist/actors/contract.js +7 -1
  46. package/dist/actors/local-agent/cli.js +1 -1
  47. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  48. package/dist/actors/scripted-browser/journey.js +15 -4
  49. package/dist/actors/scripted-browser/steps.js +18 -0
  50. package/dist/actors/scripted-browser/types.d.ts +11 -1
  51. package/dist/actors/stop-conditions.js +1 -3
  52. package/dist/analysis/automatic-completion.d.ts +13 -8
  53. package/dist/analysis/automatic-completion.js +14 -8
  54. package/dist/analysis/automatic-config.d.ts +1 -1
  55. package/dist/analysis/automatic-config.js +2 -2
  56. package/dist/analysis/automatic.d.ts +10 -4
  57. package/dist/analysis/automatic.js +17 -13
  58. package/dist/analysis/diagnostics.d.ts +23 -0
  59. package/dist/analysis/diagnostics.js +112 -0
  60. package/dist/analysis/evidence-sources.js +2 -2
  61. package/dist/analysis/evidence.js +6 -6
  62. package/dist/analysis/execute.d.ts +7 -1
  63. package/dist/analysis/execute.js +39 -12
  64. package/dist/analysis/job.d.ts +8 -5
  65. package/dist/analysis/job.js +15 -14
  66. package/dist/analysis/load.d.ts +1 -1
  67. package/dist/analysis/load.js +5 -5
  68. package/dist/analysis/provider.d.ts +9 -1
  69. package/dist/analysis/restricted-codex.d.ts +2 -0
  70. package/dist/analysis/restricted-codex.js +10 -1
  71. package/dist/analysis/service.d.ts +2 -0
  72. package/dist/analysis/service.js +31 -12
  73. package/dist/analysis/sharing.d.ts +2 -2
  74. package/dist/analysis/sharing.js +5 -5
  75. package/dist/analysis/store-executions.d.ts +5 -5
  76. package/dist/analysis/store-executions.js +12 -12
  77. package/dist/analysis/store.d.ts +4 -4
  78. package/dist/analysis/store.js +13 -13
  79. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  80. package/dist/cli/commands/analysis-signals.js +4 -1
  81. package/dist/cli/commands/analyze.js +4 -2
  82. package/dist/cli/commands/comms.js +8 -1
  83. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  84. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  85. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  86. package/dist/cli/commands/lab-route-preview.js +3 -4
  87. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  88. package/dist/cli/commands/lab-route-run.js +6 -2
  89. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  90. package/dist/cli/commands/lab-route-scripted.js +0 -1
  91. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  92. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  93. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  94. package/dist/cli/commands/lab-route-terminal.js +0 -1
  95. package/dist/cli/commands/lab-run.js +76 -45
  96. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  97. package/dist/cli/commands/lab.js +12 -6
  98. package/dist/cli/commands/observe.js +22 -0
  99. package/dist/cli/commands/run-signals.d.ts +30 -0
  100. package/dist/cli/commands/run-signals.js +146 -0
  101. package/dist/cli/commands/runs.js +10 -8
  102. package/dist/cli/commands/watch.js +12 -10
  103. package/dist/cli/doctor.d.ts +3 -0
  104. package/dist/cli/doctor.js +10 -2
  105. package/dist/cli/io.d.ts +5 -4
  106. package/dist/cli/io.js +12 -8
  107. package/dist/cli/program.js +3 -3
  108. package/dist/cli/renamed-options.d.ts +11 -0
  109. package/dist/cli/renamed-options.js +18 -0
  110. package/dist/cli/telemetry.d.ts +2 -2
  111. package/dist/cli/telemetry.js +1 -1
  112. package/dist/comms/capture-surface.d.ts +1 -1
  113. package/dist/comms/catch-host.d.ts +1 -1
  114. package/dist/comms/connections.js +4 -4
  115. package/dist/comms/external-evidence.d.ts +27 -0
  116. package/dist/comms/external-evidence.js +93 -0
  117. package/dist/comms/lease-store.js +7 -7
  118. package/dist/comms/types.js +1 -1
  119. package/dist/evidence/browser-hygiene.d.ts +1 -1
  120. package/dist/evidence/browser-hygiene.js +1 -1
  121. package/dist/evidence/redaction.js +1 -1
  122. package/dist/evidence/secret-scrub.d.ts +9 -0
  123. package/dist/evidence/secret-scrub.js +96 -0
  124. package/dist/feedback/draft.js +7 -9
  125. package/dist/feedback/export-bundle.js +4 -4
  126. package/dist/feedback/export.js +9 -9
  127. package/dist/feedback/feedback.d.ts +1 -1
  128. package/dist/index.d.ts +3 -6
  129. package/dist/index.js +3 -6
  130. package/dist/keys/key-resolution.d.ts +3 -1
  131. package/dist/keys/key-resolution.js +18 -16
  132. package/dist/lab/adapter-extension.d.ts +28 -6
  133. package/dist/lab/adapter-extension.js +65 -126
  134. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  135. package/dist/lab/adapter-scorer-loader.js +24 -0
  136. package/dist/lab/composition-rules.d.ts +2 -0
  137. package/dist/lab/composition-rules.js +35 -26
  138. package/dist/lab/config.js +28 -26
  139. package/dist/lab/device-presets.d.ts +2 -2
  140. package/dist/lab/discover.js +1 -3
  141. package/dist/lab/doctor.d.ts +44 -9
  142. package/dist/lab/doctor.js +149 -41
  143. package/dist/lab/init-plan.js +1 -3
  144. package/dist/lab/keys.js +1 -1
  145. package/dist/lab/lab-deps.d.ts +85 -0
  146. package/dist/lab/lab-deps.js +4 -0
  147. package/dist/lab/parse/actors.js +8 -7
  148. package/dist/lab/parse/comms.js +3 -2
  149. package/dist/lab/parse/execution.js +3 -2
  150. package/dist/lab/parse/subject-state.js +2 -1
  151. package/dist/lab/parse/subject.js +2 -1
  152. package/dist/lab/parse/values.d.ts +0 -1
  153. package/dist/lab/parse/values.js +0 -3
  154. package/dist/lab/persona-resolve.d.ts +3 -3
  155. package/dist/lab/persona-resolve.js +4 -4
  156. package/dist/lab/persona.js +1 -3
  157. package/dist/lab/plan-base.d.ts +6 -2
  158. package/dist/lab/plan-base.js +22 -7
  159. package/dist/lab/plan-participants.d.ts +5 -5
  160. package/dist/lab/plan-participants.js +2 -2
  161. package/dist/lab/plan-types.d.ts +33 -7
  162. package/dist/lab/plan.d.ts +3 -11
  163. package/dist/lab/plan.js +18 -42
  164. package/dist/lab/preflight-result.js +0 -2
  165. package/dist/lab/preflight.d.ts +0 -3
  166. package/dist/lab/preflight.js +1 -1
  167. package/dist/lab/requirements.d.ts +20 -0
  168. package/dist/lab/requirements.js +54 -0
  169. package/dist/lab/route-inputs.d.ts +23 -12
  170. package/dist/lab/route-inputs.js +48 -51
  171. package/dist/lab/routing.d.ts +19 -24
  172. package/dist/lab/routing.js +14 -47
  173. package/dist/lab/run-lab-events.d.ts +6 -11
  174. package/dist/lab/run-lab-events.js +3 -11
  175. package/dist/lab/run-lab-homes.d.ts +64 -0
  176. package/dist/lab/run-lab-homes.js +3 -0
  177. package/dist/lab/run-lab-options.d.ts +12 -66
  178. package/dist/lab/run-lab-options.js +45 -275
  179. package/dist/lab/summary.d.ts +9 -4
  180. package/dist/lab/summary.js +15 -8
  181. package/dist/lab/types.d.ts +132 -132
  182. package/dist/lab/validation.d.ts +15 -15
  183. package/dist/lab/validation.js +28 -28
  184. package/dist/lab/warnings.js +20 -19
  185. package/dist/observer/artifact.d.ts +1 -1
  186. package/dist/observer/artifact.js +3 -3
  187. package/dist/observer/data.js +2 -2
  188. package/dist/observer/render.js +2 -2
  189. package/dist/observer/run-routes.d.ts +1 -1
  190. package/dist/observer/run-routes.js +5 -5
  191. package/dist/observer/serve.d.ts +17 -0
  192. package/dist/observer/serve.js +34 -3
  193. package/dist/observer-app.html +1 -1
  194. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  195. package/dist/routes/computer-use/bundle-parts.js +10 -3
  196. package/dist/routes/computer-use/bundle.d.ts +4 -11
  197. package/dist/routes/computer-use/bundle.js +9 -15
  198. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  199. package/dist/routes/computer-use/diagnostics.js +1 -1
  200. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  201. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  202. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  203. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  204. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  205. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  206. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  207. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  208. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  209. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  210. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  211. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  212. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  213. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  214. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  215. package/dist/routes/computer-use/external-comms.js +19 -43
  216. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  217. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  218. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  219. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  220. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  221. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  222. package/dist/routes/computer-use/live-flush.js +19 -27
  223. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
  224. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  225. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  226. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  227. package/dist/routes/computer-use/local-vm.js +39 -66
  228. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  229. package/dist/routes/computer-use/participant-desktop.js +5 -25
  230. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  231. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  232. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  233. package/dist/routes/computer-use/participant-facts.js +12 -1
  234. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  235. package/dist/routes/computer-use/participant-model.js +58 -33
  236. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  237. package/dist/routes/computer-use/participant-prompt.js +4 -4
  238. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  239. package/dist/routes/computer-use/participant-runs.js +8 -8
  240. package/dist/routes/computer-use/plan.d.ts +21 -29
  241. package/dist/routes/computer-use/plan.js +59 -65
  242. package/dist/routes/computer-use/preflight.d.ts +6 -11
  243. package/dist/routes/computer-use/preflight.js +26 -18
  244. package/dist/routes/computer-use/rerun-selection.js +10 -6
  245. package/dist/routes/computer-use/result.d.ts +1 -1
  246. package/dist/routes/computer-use/result.js +40 -30
  247. package/dist/routes/computer-use/route.d.ts +3 -4
  248. package/dist/routes/computer-use/route.js +21 -19
  249. package/dist/routes/computer-use/self-report.d.ts +2 -2
  250. package/dist/routes/computer-use/self-report.js +4 -4
  251. package/dist/routes/computer-use/setup.d.ts +8 -17
  252. package/dist/routes/computer-use/setup.js +98 -86
  253. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  254. package/dist/routes/computer-use/single-bundle.js +20 -25
  255. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  256. package/dist/routes/computer-use/subject-projection.js +20 -19
  257. package/dist/routes/computer-use/types.d.ts +169 -211
  258. package/dist/routes/computer-use/types.js +13 -6
  259. package/dist/routes/preview.js +0 -1
  260. package/dist/routes/scripted/bundle.d.ts +3 -6
  261. package/dist/routes/scripted/bundle.js +11 -16
  262. package/dist/routes/scripted/plan.d.ts +5 -7
  263. package/dist/routes/scripted/plan.js +6 -4
  264. package/dist/routes/scripted/result.d.ts +4 -1
  265. package/dist/routes/scripted/result.js +10 -6
  266. package/dist/routes/scripted/route.js +10 -11
  267. package/dist/routes/scripted/scenario.d.ts +1 -1
  268. package/dist/routes/scripted/scenario.js +1 -1
  269. package/dist/routes/scripted/setup.d.ts +3 -2
  270. package/dist/routes/scripted/setup.js +22 -21
  271. package/dist/routes/scripted/subject.d.ts +8 -3
  272. package/dist/routes/scripted/subject.js +11 -6
  273. package/dist/routes/scripted/surface-records.js +1 -1
  274. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  275. package/dist/routes/scripted/surface-sessions.js +4 -4
  276. package/dist/routes/scripted/types.d.ts +19 -36
  277. package/dist/routes/scripted/types.js +1 -2
  278. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  279. package/dist/routes/shared-world/bundle.d.ts +2 -2
  280. package/dist/routes/shared-world/bundle.js +22 -26
  281. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  282. package/dist/routes/shared-world/checkpoints.js +4 -4
  283. package/dist/routes/shared-world/comms.d.ts +5 -4
  284. package/dist/routes/shared-world/comms.js +28 -41
  285. package/dist/routes/shared-world/external-public.d.ts +5 -5
  286. package/dist/routes/shared-world/external-public.js +19 -20
  287. package/dist/routes/shared-world/handoff.d.ts +4 -4
  288. package/dist/routes/shared-world/handoff.js +50 -50
  289. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  290. package/dist/routes/shared-world/lobby-code.js +13 -13
  291. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  292. package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
  293. package/dist/routes/shared-world/plan.d.ts +2 -6
  294. package/dist/routes/shared-world/plan.js +1 -2
  295. package/dist/routes/shared-world/provenance.d.ts +4 -4
  296. package/dist/routes/shared-world/provenance.js +4 -4
  297. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  298. package/dist/routes/shared-world/provisioned.js +48 -41
  299. package/dist/routes/shared-world/result.js +31 -19
  300. package/dist/routes/shared-world/route.js +37 -41
  301. package/dist/routes/shared-world/setup.d.ts +5 -4
  302. package/dist/routes/shared-world/setup.js +12 -14
  303. package/dist/routes/shared-world/types.d.ts +53 -126
  304. package/dist/routes/shared-world/types.js +2 -2
  305. package/dist/routes/terminal/adapter.d.ts +8 -8
  306. package/dist/routes/terminal/adapter.js +28 -125
  307. package/dist/routes/terminal/bundle.d.ts +7 -12
  308. package/dist/routes/terminal/bundle.js +24 -34
  309. package/dist/routes/terminal/credentials.d.ts +2 -2
  310. package/dist/routes/terminal/credentials.js +16 -16
  311. package/dist/routes/terminal/dry-run.d.ts +1 -1
  312. package/dist/routes/terminal/dry-run.js +9 -11
  313. package/dist/routes/terminal/encoding.d.ts +1 -1
  314. package/dist/routes/terminal/encoding.js +2 -2
  315. package/dist/routes/terminal/ledger.d.ts +6 -6
  316. package/dist/routes/terminal/ledger.js +9 -9
  317. package/dist/routes/terminal/live-finish.d.ts +1 -2
  318. package/dist/routes/terminal/live-finish.js +21 -20
  319. package/dist/routes/terminal/live-sandbox.d.ts +4 -2
  320. package/dist/routes/terminal/live-sandbox.js +25 -21
  321. package/dist/routes/terminal/participant-text.d.ts +23 -0
  322. package/dist/routes/terminal/participant-text.js +165 -0
  323. package/dist/routes/terminal/plan.d.ts +2 -6
  324. package/dist/routes/terminal/plan.js +13 -9
  325. package/dist/routes/terminal/recorder.d.ts +6 -1
  326. package/dist/routes/terminal/recorder.js +12 -4
  327. package/dist/routes/terminal/result.js +4 -4
  328. package/dist/routes/terminal/route.js +26 -26
  329. package/dist/routes/terminal/runtime.d.ts +3 -2
  330. package/dist/routes/terminal/runtime.js +3 -3
  331. package/dist/routes/terminal/sandbox.d.ts +5 -3
  332. package/dist/routes/terminal/sandbox.js +13 -16
  333. package/dist/routes/terminal/session.js +16 -14
  334. package/dist/routes/terminal/token-usage.js +5 -5
  335. package/dist/routes/terminal/trace.d.ts +5 -8
  336. package/dist/routes/terminal/trace.js +9 -64
  337. package/dist/routes/terminal/types.d.ts +85 -93
  338. package/dist/routes/terminal/types.js +9 -4
  339. package/dist/run/active-runs.d.ts +13 -0
  340. package/dist/run/active-runs.js +12 -0
  341. package/dist/run/bundle-shape.d.ts +2 -1
  342. package/dist/run/bundle-shape.js +4 -4
  343. package/dist/run/bundle.d.ts +63 -56
  344. package/dist/run/bundle.js +9 -8
  345. package/dist/run/cost-summary.js +3 -2
  346. package/dist/run/costs.d.ts +6 -6
  347. package/dist/run/costs.js +10 -10
  348. package/dist/run/detail.d.ts +5 -5
  349. package/dist/run/detail.js +6 -6
  350. package/dist/run/dry-run.js +5 -12
  351. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  352. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  353. package/dist/run/feedback-shape.js +1 -1
  354. package/dist/run/judge.d.ts +16 -4
  355. package/dist/run/judge.js +24 -7
  356. package/dist/run/locate.d.ts +2 -0
  357. package/dist/run/locate.js +3 -1
  358. package/dist/run/outcomes.d.ts +3 -3
  359. package/dist/run/outcomes.js +3 -3
  360. package/dist/run/participant-records.d.ts +2 -2
  361. package/dist/run/participant-records.js +2 -2
  362. package/dist/run/paths.js +1 -1
  363. package/dist/run/pricing.d.ts +19 -9
  364. package/dist/run/pricing.js +30 -18
  365. package/dist/run/projection.d.ts +13 -13
  366. package/dist/run/projection.js +8 -8
  367. package/dist/run/reclaim.d.ts +7 -1
  368. package/dist/run/reclaim.js +24 -4
  369. package/dist/run/results.d.ts +1 -1
  370. package/dist/run/run-index.d.ts +1 -1
  371. package/dist/run/run-index.js +11 -11
  372. package/dist/run/run.d.ts +4 -2
  373. package/dist/run/run.js +9 -5
  374. package/dist/run/sandbox-receipts.d.ts +4 -4
  375. package/dist/run/sandbox-receipts.js +4 -4
  376. package/dist/run/shared-world-evidence.d.ts +47 -47
  377. package/dist/run/shared-world-shape.d.ts +3 -3
  378. package/dist/run/shared-world-shape.js +11 -11
  379. package/dist/run/stats.d.ts +5 -5
  380. package/dist/run/stats.js +8 -8
  381. package/dist/run/status.d.ts +16 -6
  382. package/dist/run/status.js +31 -8
  383. package/dist/run/streams.d.ts +26 -19
  384. package/dist/run/terminal-contract.d.ts +5 -5
  385. package/dist/run/terminal-contract.js +4 -4
  386. package/dist/run/transient-comms-secrets.d.ts +5 -0
  387. package/dist/run/transient-comms-secrets.js +12 -0
  388. package/dist/run-lab.d.ts +36 -34
  389. package/dist/run-lab.js +41 -37
  390. package/dist/subject/desktop-cli.d.ts +1 -1
  391. package/dist/subject/desktop-cli.js +1 -1
  392. package/dist/subject/local-tree-archive.d.ts +1 -1
  393. package/dist/subject/local-tree-archive.js +4 -4
  394. package/dist/subject/local-tree.d.ts +2 -2
  395. package/dist/subject/local-tree.js +1 -1
  396. package/dist/subject/node-bootstrap.d.ts +1 -1
  397. package/dist/subject/node-bootstrap.js +4 -4
  398. package/dist/subject/runtime.js +5 -5
  399. package/dist/subject/serve.js +1 -1
  400. package/dist/subject/steps.d.ts +4 -4
  401. package/dist/subject/steps.js +5 -5
  402. package/dist/substrates/desktop-session.d.ts +2 -0
  403. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  404. package/dist/substrates/e2b/cdp-probe.js +1 -1
  405. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  406. package/dist/substrates/e2b/desktop-browser.js +4 -4
  407. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  408. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  409. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  410. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  411. package/dist/substrates/e2b/desktop-media.js +2 -2
  412. package/dist/substrates/e2b/sandbox.d.ts +2 -0
  413. package/dist/substrates/e2b/sandbox.js +22 -8
  414. package/dist/substrates/e2b/sdk.d.ts +12 -1
  415. package/dist/substrates/e2b/sdk.js +30 -9
  416. package/dist/substrates/local/runtime-host.d.ts +2 -0
  417. package/dist/substrates/local/runtime-host.js +6 -0
  418. package/dist/tui/actions.d.ts +7 -5
  419. package/dist/tui/actions.js +18 -9
  420. package/dist/tui-app.js +42 -42
  421. package/dist/verify/actor.d.ts +10 -10
  422. package/dist/verify/actor.js +15 -15
  423. package/dist/verify/artifacts.d.ts +1 -1
  424. package/dist/verify/artifacts.js +3 -3
  425. package/dist/verify/costs.d.ts +2 -2
  426. package/dist/verify/costs.js +2 -2
  427. package/dist/verify/liveness.d.ts +1 -1
  428. package/dist/verify/liveness.js +4 -1
  429. package/dist/verify/rerun.d.ts +1 -1
  430. package/dist/verify/rerun.js +1 -1
  431. package/dist/verify/shared-world.js +2 -2
  432. package/dist/verify/verify.js +6 -6
  433. package/docs/README.md +1 -1
  434. package/docs/architecture/actor-contract.md +60 -22
  435. package/docs/architecture/desktop-sessions.md +9 -9
  436. package/docs/architecture/external-public-shared-world.md +5 -0
  437. package/docs/architecture/observer.md +4 -4
  438. package/docs/architecture/restricted-codex-analysis.md +40 -4
  439. package/docs/architecture/state-driven-executor.md +4 -5
  440. package/docs/architecture/task-protocol-support.md +3 -5
  441. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  442. package/docs/contracts/run-bundle.md +10 -8
  443. package/docs/contracts/schemas.md +109 -53
  444. package/docs/contracts/study-analysis.md +24 -0
  445. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  446. package/docs/product/automatic-analysis.md +1 -0
  447. package/docs/ramp/README.md +2 -1
  448. package/package.json +4 -4
  449. package/skills/humanish/SKILL.md +3 -2
  450. package/skills/humanish/agents/openai.yaml +1 -1
  451. package/dist/deprecated.d.ts +0 -90
  452. package/dist/deprecated.js +0 -106
  453. package/dist/lab/bag-overrides.d.ts +0 -18
  454. package/dist/lab/bag-overrides.js +0 -121
  455. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  456. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  457. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  458. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  459. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -8,39 +8,39 @@
8
8
  // live-sandbox.ts and live-finish.ts); a dry plan publishes its contract bundle (dry-run.ts);
9
9
  // 4. automatic analysis of a run that published its final bundle.
10
10
  //
11
- // THE SAFETY CONTRACT (docs/goals/terminal-product-lane/goal.md) is enforced BY CONSTRUCTION in
12
- // the files each item names, and CHECKED by the verifier (verify/actor.ts
11
+ // The safety contract (`docs/goals/terminal-product-lane/goal.md`) is enforced by construction in
12
+ // the files each item names, and checked by the verifier (verify/actor.ts
13
13
  // validateTerminalProductEvidence):
14
- // 1. EXPLICIT KEY PLACEMENT. openai-env (default) injects the raw runtime key command-scoped,
15
- // NEVER Sandbox.create({envs}). Opt-in openai-egress sends it only in the host-side E2B
14
+ // 1. Explicit key placement. openai-env (default) injects the raw runtime key command-scoped,
15
+ // never through Sandbox.create({envs}). Opt-in openai-egress sends it only in the host-side E2B
16
16
  // header transform and passes an inert command placeholder. The proxy is spendable by every
17
17
  // sandbox process from creation; this protects the raw key, not provider spending.
18
18
  // Enforced in credentials.ts and runtime-auth.ts.
19
- // 2. FAIL-CLOSED CAP. The live key is never exercised without scenario.caps in force: maxUsd
19
+ // 2. Fail-closed cap. The live key is never exercised without scenario.caps in force: maxUsd
20
20
  // (default/require 0 = no-spend) + maxMinutes (wall-clock kill of the codex command).
21
21
  // Enforced in plan.ts (caps required), live-sandbox.ts and lifetime.ts (the wall clock).
22
- // 3. PUBLIC SURFACES ONLY. The mission references only subject.product.publicSurfaces + the
23
- // author mission. No clone, no private-source access — nothing is git-cloned in this lane.
22
+ // 3. Public surfaces only. The mission references only subject.product.publicSurfaces + the
23
+ // author mission. No clone, no private-source access — nothing is git-cloned on this route.
24
24
  // Enforced in session.ts, which composes the prompt.
25
- // 4. DENY-BY-DEFAULT CREDENTIALS. The command envs are built from an ALLOWLIST of ONLY the
25
+ // 4. Deny-by-default credentials. The command envs are built from an allowlist holding only the
26
26
  // declared runtime key; GITHUB_TOKEN/GH_TOKEN/payment/deploy/db/media keys are excluded by
27
27
  // construction (a banned-name guard also fails closed if one is ever requested).
28
28
  // Enforced in credentials.ts.
29
- // 5. NO SECRET VALUES IN EVIDENCE. Every captured byte (event stream, transcript, command logs,
29
+ // 5. No secret values in evidence. Every captured byte (event stream, transcript, command logs,
30
30
  // agent report, metadata) passes scrubKnownValues (literal scrub of the runtime key + any
31
- // provisioned values, >=4 chars, PRE-truncation) THEN redactText (shape patterns) BEFORE
32
- // persisting. The transport is labeled HONESTLY (exec-stream/snapshot, NOT an interactive pty).
31
+ // provisioned values, >=4 chars, before truncation), then redactText (shape patterns), before
32
+ // persisting. The transport is labeled exec-stream/snapshot; there is no interactive pty.
33
33
  // Enforced in recorder.ts, with the scrubber session.ts builds.
34
- // 6. METADATA POSITIVE ALLOWLIST. buildSandboxMetadata(allowlist) is the ONLY way metadata is
34
+ // 6. Metadata positive allowlist. buildSandboxMetadata(allowlist) is the only way metadata is
35
35
  // set; it carries solely non-secret labels (mode/tool/labId/simId/provider/runId).
36
36
  // Enforced in credentials.ts.
37
- // 7. STDIN DISABLED + INTERVENTIONS LEDGER. stdin is never wired to the codex command; the
38
- // bundle ALWAYS carries an interventions ledger (empty array is valid + required-present).
37
+ // 7. Stdin disabled + interventions ledger. stdin is never wired to the codex command; the
38
+ // bundle always carries an interventions ledger (empty array is valid + required-present).
39
39
  // Enforced in live-sandbox.ts (stdin) and recorder.ts (the ledger).
40
- // 8. PROVEN CLEANUP, BY ID, NEVER ACCOUNT-WIDE. Sandbox.kill(id) in a finally; the cleanup
41
- // proof is BY EXACT ID: kill(id)'s own found-and-killed boolean, confirmed further by
40
+ // 8. Proven cleanup, by id, never account-wide. Sandbox.kill(id) in a finally; the cleanup
41
+ // proof is by exact id: kill(id)'s own found-and-killed boolean, confirmed further by
42
42
  // Sandbox.getInfo(id) when the SDK exposes it (a thrown SandboxNotFoundError means gone).
43
- // humanish NEVER calls Sandbox.list to prove cleanup, so a shared operator key never reaches a
43
+ // humanish never calls Sandbox.list to prove cleanup, so a shared operator key never reaches a
44
44
  // sandbox it did not create. A live run that cannot prove teardown fails closed.
45
45
  // Enforced in sandbox.ts.
46
46
  import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
@@ -50,18 +50,18 @@ import { runScope } from "../../run/run.js";
50
50
  import { planTerminalLab } from "./plan.js";
51
51
  import { runDryTerminalLab } from "./dry-run.js";
52
52
  import { checkLiveTerminalMachine, runLiveTerminalSession } from "./session.js";
53
- import { terminalInputWithScorer } from "../../lab/route-inputs.js";
53
+ import { terminalRouteScorer } from "../../lab/adapter-scorer-loader.js";
54
+ import { withLateScorer } from "../../lab/route-inputs.js";
54
55
  import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
55
56
  /**
56
57
  * The config-taking entry point. It plans, returns a refusal with the same envelope and analysis
57
58
  * record the route has always returned, and otherwise runs the plan.
58
59
  */
59
60
  export async function runTerminalProductLab(options) {
60
- const { config, dryRun, lab, ...input } = options;
61
+ const { config, dryRun, ...input } = options;
61
62
  const planned = planTerminalLab(config, {
62
63
  dryRun,
63
- ...(lab === undefined ? {} : { lab }),
64
- ...(input.hooks === undefined ? {} : { hooks: input.hooks }),
64
+ hasCostProbe: input.deps?.costProbe !== undefined,
65
65
  });
66
66
  if (planned.ok)
67
67
  return runTerminalPlan(planned.plan, input);
@@ -84,7 +84,7 @@ export function terminalLabRefusal(options, refusal) {
84
84
  };
85
85
  // A refusal starts no run, so a declared or default analysis is recorded as skipped.
86
86
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
87
- return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options.automaticAnalysis, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
87
+ return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
88
88
  }
89
89
  /**
90
90
  * Run a terminal plan. The run scope gives a direct library caller the same run lifetime the CLI
@@ -106,11 +106,11 @@ export async function admitTerminalPlan(plan, input) {
106
106
  return { ok: false, outcome: terminalOutcome(admission.result) };
107
107
  return {
108
108
  ok: true,
109
- run: async (scorer) => terminalOutcome(await runAdmittedTerminalRun(admission.admitted, terminalInputWithScorer(input, scorer))),
109
+ run: async (scorer) => terminalOutcome(await runAdmittedTerminalRun(admission.admitted, withLateScorer(input, scorer, terminalRouteScorer))),
110
110
  };
111
111
  }
112
112
  function terminalOutcome(result) {
113
- return { route: "terminal", backend: "terminal", result };
113
+ return { route: "terminal", result };
114
114
  }
115
115
  /**
116
116
  * A live plan's local checks, made outside any run scope. A refusal is the result runTerminalPlan
@@ -132,7 +132,7 @@ async function runAdmittedTerminalRun(admitted, input) {
132
132
  return completeTerminalAnalysis(admitted.plan, input, result, finished);
133
133
  }
134
134
  function completeTerminalAnalysis(plan, input, result, finished) {
135
- return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input.automaticAnalysis, {
135
+ return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
136
136
  ...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
137
137
  preferLargerOutput: plan.analysis?.preferLargerOutput === true,
138
138
  });
@@ -157,7 +157,7 @@ async function runTerminalPlanInScope(admitted, input, scope) {
157
157
  const cwd = path.resolve(input.cwd);
158
158
  const { warnings } = admitted;
159
159
  const failed = terminalFailure(admitted.plan, input, warnings);
160
- // LIVE path: the real in-sandbox agent session. A separate orchestrator owns the
160
+ // Live path: the real in-sandbox agent session. A separate orchestrator owns the
161
161
  // create -> inject (command-scoped) -> run -> capture -> teardown lifecycle so the dry-run path
162
162
  // below stays a pure contract builder. It enforces the safety contract by construction (the
163
163
  // keyPlacement-routed command-scoped key, the deny-by-default allowlist, the fail-closed cap,
@@ -6,9 +6,10 @@ export declare function isExactRuntimeVersion(value: unknown): value is string;
6
6
  /** Captured Codex CLI output: `codex-cli 0.153.3\n`. Other shapes fail closed. */
7
7
  export declare function parseTerminalRuntimeVersion(stdout: string): string | undefined;
8
8
  export declare function buildRuntimeVersionCommand(requestedVersion?: string): string;
9
- export declare function buildRuntimeExecPrefix(version: string, model?: string, reasoningEffort?: ReasoningEffort): string;
9
+ export declare function buildRuntimeExecPrefix(version: string, model: string, reasoningEffort?: ReasoningEffort): string;
10
10
  export declare function declaredRuntimeProvenance(args: {
11
11
  version?: string;
12
- model?: string;
12
+ model: string;
13
+ modelSource: "declared" | "humanish_default";
13
14
  reasoningEffort?: ReasoningEffort;
14
15
  }): ActorRuntimeProvenance;
@@ -26,7 +26,7 @@ export function buildRuntimeExecPrefix(version, model, reasoningEffort) {
26
26
  if (!isExactRuntimeVersion(version))
27
27
  throw new Error("Codex execution requires a verified exact runtime version.");
28
28
  return (`npm_config_update_notifier=false npx -y ${TERMINAL_RUNTIME_PACKAGE}@${version} exec` +
29
- (model === undefined ? "" : ` --model ${shellQuote(model)}`) +
29
+ ` --model ${shellQuote(model)}` +
30
30
  (reasoningEffort === undefined
31
31
  ? ""
32
32
  : ` -c ${shellQuote(`model_reasoning_effort=${JSON.stringify(reasoningEffort)}`)}`));
@@ -37,8 +37,8 @@ export function declaredRuntimeProvenance(args) {
37
37
  package: TERMINAL_RUNTIME_PACKAGE,
38
38
  requestedVersion: args.version ?? "latest",
39
39
  versionStatus: "unobserved",
40
- ...(args.model === undefined ? {} : { requestedModel: args.model }),
41
- modelStatus: args.model === undefined ? "runtime_default_unobserved" : "declared",
40
+ requestedModel: args.model,
41
+ modelStatus: args.modelSource,
42
42
  ...(args.reasoningEffort === undefined
43
43
  ? {}
44
44
  : { requestedReasoningEffort: args.reasoningEffort }),
@@ -2,13 +2,13 @@ import type { OwnedDesktopAllocation } from "../../substrates/desktop-session.js
2
2
  import { E2BDesktopStartupError, type E2BDesktopModule } from "../../substrates/e2b/sdk.js";
3
3
  import type { TerminalLedgers } from "./types.js";
4
4
  /**
5
- * Tear the sandbox down and PROVE it BY EXACT ID -- NEVER Sandbox.list (humanish must never
5
+ * Tear the sandbox down and prove it by exact id, never by Sandbox.list (humanish must never
6
6
  * enumerate the operator's E2B account; see docs/principles/invariants-and-defaults.md). The
7
7
  * allocation's release (src/substrates/e2b/sandbox.ts) kills the exact id and reads the answer the
8
8
  * same way every route does: true is terminated, false or a not-found error is already gone. That
9
- * is the PRIMARY proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
9
+ * is the primary proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
10
10
  * a second by-id confirmation that the exact sandbox is gone; a returned SandboxInfo with a live
11
- * state means teardown is NOT confirmed. Never throws -- teardown failure is recorded, the caller
11
+ * state means teardown is unconfirmed. Never throws: teardown failure is recorded, and the caller
12
12
  * fails closed on an unproven teardown.
13
13
  */
14
14
  export declare function teardownSandbox(args: {
@@ -17,6 +17,8 @@ export declare function teardownSandbox(args: {
17
17
  /** For the Sandbox.getInfo(id) re-check only. */
18
18
  sandboxModule: E2BDesktopModule | undefined;
19
19
  startupCleanup?: E2BDesktopStartupError["cleanup"];
20
+ /** Why the startup guard's cleanup is unconfirmed, when it knows. */
21
+ startupCleanupDetail?: string | undefined;
20
22
  requestTimeoutMs: number;
21
23
  sanitize: (text: string) => string;
22
24
  recordLifecycle: (event: string, message: string) => void;
@@ -1,27 +1,28 @@
1
1
  import { toErrorMessage } from "../../evidence/redaction.js";
2
2
  import { E2BDesktopStartupError, isSandboxNotFoundError, } from "../../substrates/e2b/sdk.js";
3
+ import { releaseUnavailableDetail } from "../../substrates/e2b/sandbox.js";
3
4
  /**
4
- * Tear the sandbox down and PROVE it BY EXACT ID -- NEVER Sandbox.list (humanish must never
5
+ * Tear the sandbox down and prove it by exact id, never by Sandbox.list (humanish must never
5
6
  * enumerate the operator's E2B account; see docs/principles/invariants-and-defaults.md). The
6
7
  * allocation's release (src/substrates/e2b/sandbox.ts) kills the exact id and reads the answer the
7
8
  * same way every route does: true is terminated, false or a not-found error is already gone. That
8
- * is the PRIMARY proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
9
+ * is the primary proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
9
10
  * a second by-id confirmation that the exact sandbox is gone; a returned SandboxInfo with a live
10
- * state means teardown is NOT confirmed. Never throws -- teardown failure is recorded, the caller
11
+ * state means teardown is unconfirmed. Never throws: teardown failure is recorded, and the caller
11
12
  * fails closed on an unproven teardown.
12
13
  */
13
14
  export async function teardownSandbox(args) {
14
- const { allocation, sandboxModule, startupCleanup, requestTimeoutMs, sanitize, recordLifecycle, warnings, } = args;
15
+ const { allocation, sandboxModule, startupCleanup, startupCleanupDetail, requestTimeoutMs, sanitize, recordLifecycle, warnings, } = args;
15
16
  if (allocation === undefined || !sandboxModule) {
16
- // create() can reject AFTER its constructor acquired a handle. The default loader retains
17
- // that authority and reclaims it before rejecting; the lane itself never receives its ID.
17
+ // create() can reject after its constructor acquired a handle. The default loader retains
18
+ // that authority and reclaims it before rejecting; the route itself never receives its ID.
18
19
  if (startupCleanup === "killed" || startupCleanup === "already_gone") {
19
20
  const reason = `desktop startup guard confirmed its acquired sandbox ${startupCleanup === "killed" ? "was killed" : "was already gone"}`;
20
21
  recordLifecycle("terminal-lab.cleanup.killed", reason);
21
22
  return { killed: true, remaining: 0, reason };
22
23
  }
23
24
  const reason = startupCleanup === "unconfirmed"
24
- ? "desktop startup guard could not confirm cleanup of its acquired sandbox; provider timeout remains the backstop"
25
+ ? `desktop startup guard could not confirm cleanup of its acquired sandbox${startupCleanupDetail === undefined ? "" : ` (${startupCleanupDetail})`}; provider timeout remains the backstop`
25
26
  : "create did not return a sandbox; the participant has no acquired handle and cannot establish allocation or cleanup";
26
27
  recordLifecycle("terminal-lab.cleanup.unconfirmed", reason);
27
28
  return { killed: false, remaining: -1, reason };
@@ -30,11 +31,7 @@ export async function teardownSandbox(args) {
30
31
  const released = await allocation.close();
31
32
  if (released.status !== "released") {
32
33
  if (released.status === "unconfirmed" && released.reason === "release_unavailable") {
33
- return {
34
- killed: false,
35
- remaining: -1,
36
- reason: "installed @e2b/desktop SDK does not expose Sandbox.kill; server-side kill-on-timeout will reclaim the sandbox",
37
- };
34
+ return { killed: false, remaining: -1, reason: releaseUnavailableDetail(released.detail) };
38
35
  }
39
36
  if (released.status === "unconfirmed" && released.reason === "release_failed") {
40
37
  const sanitizedError = sanitize(toErrorMessage(released.error));
@@ -52,12 +49,12 @@ export async function teardownSandbox(args) {
52
49
  recordLifecycle("terminal-lab.cleanup.unconfirmed", `Sandbox ${sandboxId} ${reason}.`);
53
50
  return { killed: false, remaining: -1, reason };
54
51
  }
55
- // BY-ID verification only, from here down: NEVER Sandbox.list. A released result is itself proof
52
+ // By-id verification only, from here down: never Sandbox.list. A released result is itself proof
56
53
  // the exact sandbox is gone: terminated when kill(id) found and killed it, already gone when
57
54
  // kill(id) answered false or threw not-found (a 404, e.g. the server-side kill-on-timeout raced
58
55
  // ahead). Both mean "this id is no longer running." Sandbox.getInfo(id), when the SDK exposes
59
56
  // it, adds a second by-id confirmation; the only thing that overturns the release proof is
60
- // getInfo returning a LIVE sandbox for this exact id.
57
+ // getInfo returning a live sandbox for this exact id.
61
58
  const killNote = released.reason === "terminated"
62
59
  ? "kill(id) returned true (found and killed)"
63
60
  : "kill(id) found the exact sandbox already gone (404)";
@@ -88,8 +85,8 @@ export async function teardownSandbox(args) {
88
85
  reason: `reclaimed by id; getInfo(id) confirms the exact sandbox no longer exists (SandboxNotFoundError)`,
89
86
  };
90
87
  }
91
- // getInfo(id) failed for a reason OTHER than "not found" (e.g. a transient network error):
92
- // no second by-id confirmation is available, so the RESOLVED kill(id) call stands as the proof
88
+ // getInfo(id) failed for a reason other than "not found" (e.g. a transient network error):
89
+ // no second by-id confirmation is available, so the resolved kill(id) call stands as the proof
93
90
  // of absence. Never fall back to Sandbox.list.
94
91
  const sanitizedError = sanitize(toErrorMessage(error));
95
92
  recordLifecycle("terminal-lab.cleanup.killed", `Sandbox ${sandboxId} reclaimed: ${killNote}; getInfo(id) re-verification errored (${sanitizedError}), so kill(id)'s resolved result is the proof.`);
@@ -1,4 +1,5 @@
1
1
  import { randomBytes, randomUUID } from "node:crypto";
2
+ import { missingKeys } from "../../lab/requirements.js";
2
3
  import { declaredRuntimeProvenance } from "./runtime.js";
3
4
  import { digestText, redactText, scrubLiterals } from "../../evidence/redaction.js";
4
5
  import { describeMissingKeys } from "../../keys/key-resolution.js";
@@ -15,7 +16,7 @@ import { finishLiveTerminalSession } from "./live-finish.js";
15
16
  * a declared scorer. Returns the runtime key's command-scoped placement, or the refusal.
16
17
  */
17
18
  export function checkLiveTerminalMachine(plan, input, warnings) {
18
- const env = input.hooks?.env ?? process.env;
19
+ const env = input.env ?? process.env;
19
20
  const { maxUsd } = plan.caps;
20
21
  // planTerminalLab refuses a positive maxUsd without a costProbe, so one is present here.
21
22
  if (maxUsd > 0) {
@@ -26,7 +27,8 @@ export function checkLiveTerminalMachine(plan, input, warnings) {
26
27
  if (!runtimeEnv.ok)
27
28
  return runtimeEnv;
28
29
  // The sandbox is created with E2B_API_KEY, so a missing key is refused before the run starts.
29
- if (!env.E2B_API_KEY?.trim()) {
30
+ // The runtime key above is the plan's `key-one-of`; E2B_API_KEY is its only `key`.
31
+ if (missingKeys(plan.requirements, env).length > 0) {
30
32
  return {
31
33
  ok: false,
32
34
  code: "HUMANISH_TERMINAL_LAB_KEYS_MISSING",
@@ -46,9 +48,9 @@ export async function runLiveTerminalSession(args) {
46
48
  const { plan, input, cwd, warnings, failed, scope, runtimeEnv } = args;
47
49
  const { actor, product } = plan;
48
50
  const { maxUsd, maxMinutes } = plan.caps;
49
- const hooks = input.hooks ?? {};
50
- const env = hooks.env ?? process.env;
51
- const now = hooks.now ?? (() => Date.now());
51
+ const deps = input.deps ?? {};
52
+ const env = input.env ?? process.env;
53
+ const now = deps.now ?? (() => Date.now());
52
54
  const nowIso = () => new Date(now()).toISOString();
53
55
  const prepared = await prepareLivePrompt({ plan, cwd, runtimeEnv, env, warnings });
54
56
  const { mission, physicalCwd, persona, composedPrompt, verdictNonce } = prepared;
@@ -61,7 +63,7 @@ export async function runLiveTerminalSession(args) {
61
63
  mode: "live",
62
64
  lab: plan.lab,
63
65
  renderReview: renderTerminalReviewMarkdown,
64
- observer: { open: input.open === true, render: hooks.renderObserverFn },
66
+ observer: { open: input.open === true, render: deps.renderObserver },
65
67
  now,
66
68
  });
67
69
  if (!started.ok)
@@ -77,17 +79,18 @@ export async function runLiveTerminalSession(args) {
77
79
  const e2bApiKey = env.E2B_API_KEY?.trim() ?? "";
78
80
  // The ledgers + capture buffers, mutated through the live lifecycle.
79
81
  const recorder = createTerminalRecorder({ nowIso, sanitize, knownSecretValues });
80
- const { version, model, reasoningEffort } = plan.runtime;
82
+ const { version, model, modelSource, reasoningEffort } = plan.runtime;
81
83
  const runtime = declaredRuntimeProvenance({
82
84
  ...(version === undefined ? {} : { version }),
83
- ...(model === undefined ? {} : { model: sanitize(model) }),
85
+ model: sanitize(model),
86
+ modelSource,
84
87
  ...(reasoningEffort === undefined ? {} : { reasoningEffort }),
85
88
  });
86
89
  recorder.recordLifecycle("terminal-lab.run.created", `Created live terminal-product run ${runId} (actor ${actor}, product ${product.name}). Caps: maxUsd=${maxUsd}, maxMinutes=${maxMinutes}. Subject provenance UNPINNED (public surfaces only).`);
87
90
  const session = new LiveTerminalSandbox({
88
91
  plan,
89
92
  cwd,
90
- hooks,
93
+ deps,
91
94
  now,
92
95
  nowIso,
93
96
  sanitize,
@@ -122,7 +125,6 @@ export async function runLiveTerminalSession(args) {
122
125
  plan,
123
126
  input,
124
127
  cwd,
125
- hooks,
126
128
  sanitize,
127
129
  nowIso,
128
130
  knownSecretValues,
@@ -144,7 +146,7 @@ export async function runLiveTerminalSession(args) {
144
146
  async function prepareLivePrompt(args) {
145
147
  const { plan, cwd, runtimeEnv, env, warnings } = args;
146
148
  const { product } = plan;
147
- // Compose the prompt from PUBLIC surfaces + the author mission ONLY (safety contract item 3).
149
+ // Compose the prompt from public surfaces and the author mission alone (safety contract item 3).
148
150
  // Inject a per-run verdict nonce: the agent echoes HUMANISH_ACTOR_VERDICT=<status>
149
151
  // HUMANISH_ACTOR_NONCE=<nonce>; the scorer verifies the nonce so replayed text cannot forge it.
150
152
  const mission = plan.mission ?? defaultMission(product.name);
@@ -158,8 +160,8 @@ async function prepareLivePrompt(args) {
158
160
  verdictNonce,
159
161
  });
160
162
  const promptDigest = digestText(composedPrompt);
161
- // --- Safety contract item 5: literal-scrub EVERY known value, then pattern-redact, at the source. ---
162
- // The runtime key value (+ any other provisioned value) is scrubbed by LITERAL match before
163
+ // --- Safety contract item 5: literal-scrub every known value, then pattern-redact, at the source. ---
164
+ // The runtime key value (+ any other provisioned value) is scrubbed by literal match before
163
165
  // anything persists (a key has no detectable "shape" if it is an arbitrary token); redactText is
164
166
  // the second pass for secret-SHAPED content. Applied PRE-truncation so a cut can never split a
165
167
  // value past the scrubber.
@@ -177,7 +179,7 @@ async function prepareLivePrompt(args) {
177
179
  sanitize,
178
180
  };
179
181
  }
180
- /** Compose the live prompt: PUBLIC surfaces + author mission + the verdict-nonce marker contract. */
182
+ /** Compose the live prompt: public surfaces + author mission + the verdict-nonce marker contract. */
181
183
  function composeLivePrompt(args) {
182
184
  return [
183
185
  args.personaLine,
@@ -1,6 +1,6 @@
1
- // Provider token accounting for the terminal lane (#531).
1
+ // Provider token accounting for the terminal route (#531).
2
2
  //
3
- // THE GAP THIS CLOSES. A live terminal run reported `cost.lines.provider = null` with source
3
+ // The gap this closes: a live terminal run reported `cost.lines.provider = null` with source
4
4
  // "unmeasured", and the no-spend proof then read `satisfied: true` for `maxUsd: 0` on a run that
5
5
  // had demonstrably consumed hundreds of thousands of provider tokens. The statement was honest
6
6
  // (it listed provider as unmeasured) but it conflated two very different states: having no signal
@@ -10,11 +10,11 @@
10
10
  // {"type":"turn.completed","usage":{"input_tokens":201536,"cached_input_tokens":170558,
11
11
  // "cache_write_input_tokens":30951,"output_tokens":2283,"reasoning_output_tokens":902}}
12
12
  //
13
- // So the lane can record a MEASURED token fact even when it cannot record a priced one. Rates stay
14
- // out of this module deliberately: pricing lives in src/run/pricing.ts, and the terminal lane has no
13
+ // So the route can record a measured token fact even when it cannot record a priced one. Rates stay
14
+ // out of this module deliberately: pricing lives in src/run/pricing.ts, and the terminal route has no
15
15
  // real model id to price against (it records `model: "codex"`), so the honest output is
16
16
  // tokens-known-rate-unknown rather than a guessed dollar figure.
17
- // Bounded to a single line on purpose. `[^}]*` would run past a TRUNCATED record's missing brace
17
+ // Bounded to a single line on purpose. `[^}]*` would run past a truncated record's missing brace
18
18
  // and swallow the next, valid record's body, silently dropping a real turn from the count.
19
19
  const USAGE_RE = /"type"\s*:\s*"turn\.completed"\s*,\s*"usage"\s*:\s*(\{[^}\n]*\})/g;
20
20
  function num(value) {
@@ -1,5 +1,6 @@
1
1
  import type { ActorCompletionReason, ActorPersonaRef, ActorRuntimeProvenance, ActorStatus, ActorTokenUsage, ActorTrace } from "../../actors/contract.js";
2
2
  import type { LabRuntimeAuth } from "../../lab/types.js";
3
+ import type { TerminalParticipantText } from "./participant-text.js";
3
4
  import { type CommandLogRecord, type TerminalEventRecord } from "./types.js";
4
5
  /**
5
6
  * Per-chunk sanitization cannot recognize a value split across deliveries. Redact those complete
@@ -10,9 +11,9 @@ export declare function scrubSplitKnownValues(events: TerminalEventRecord[], kno
10
11
  /** Redacted, ellipsis-prefixed tail of a captured stream/log for a message field. */
11
12
  export declare function tailOf(text: string): string;
12
13
  /**
13
- * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (lane
14
+ * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
14
15
  * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
15
- * guard (a real run bumps them; a no-op is caught). No screenshots on this lane.
16
+ * guard (a real run bumps them; a no-op is caught). No screenshots on this route.
16
17
  */
17
18
  export declare function buildTerminalActorTrace(args: {
18
19
  persona: ActorPersonaRef;
@@ -31,10 +32,6 @@ export declare function buildTerminalActorTrace(args: {
31
32
  /** Runtime-turn aggregate usage parsed from the exec stream (#531). Absent when the stream
32
33
  * carried no usage record, which stays distinct from a measured zero. */
33
34
  tokenUsage?: ActorTokenUsage;
35
+ /** The agent's own text and activity, read from the raw stdout as it arrived. */
36
+ participant: TerminalParticipantText;
34
37
  }): ActorTrace;
35
- /** Count distinct participant items in the retained Codex JSON stdout stream.
36
- * The caller supplies stdout only, after transport reconciliation and redaction.
37
- * Lifecycle, usage, launcher diagnostics, and nested command output are not activity.
38
- * Zero means no recognized item was retained, not that the participant succeeded.
39
- */
40
- export declare function countTerminalParticipantItems(stdout: string): number;
@@ -1,6 +1,5 @@
1
1
  import { ACTOR_TRACE_SCHEMA, TERMINAL_AGENT_CAPABILITIES } from "../../actors/contract.js";
2
2
  import { redactedTail } from "../../evidence/redaction.js";
3
- import { normalizeLocalActorTranscript } from "../../run/terminal-contract.js";
4
3
  import { TAIL_CHARS } from "./types.js";
5
4
  /**
6
5
  * Per-chunk sanitization cannot recognize a value split across deliveries. Redact those complete
@@ -57,9 +56,9 @@ export function tailOf(text) {
57
56
  return redactedTail(text, TAIL_CHARS);
58
57
  }
59
58
  /**
60
- * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (lane
59
+ * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
61
60
  * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
62
- * guard (a real run bumps them; a no-op is caught). No screenshots on this lane.
61
+ * guard (a real run bumps them; a no-op is caught). No screenshots on this route.
63
62
  */
64
63
  export function buildTerminalActorTrace(args) {
65
64
  const items = [
@@ -74,19 +73,7 @@ export function buildTerminalActorTrace(args) {
74
73
  outputTail: args.transcriptTail,
75
74
  },
76
75
  })),
77
- // One message item carrying the (already-redacted) transcript tail so the trace shows the agent
78
- // narrated SOMETHING — the engagement signal the no-engagement guard reads.
79
- ...(args.terminalEvents.length > 0
80
- ? [
81
- {
82
- id: "message-001",
83
- kind: "message",
84
- lifecycle: "completed",
85
- title: "agent terminal output",
86
- text: args.transcriptTail,
87
- },
88
- ]
89
- : []),
76
+ ...args.participant.items,
90
77
  ];
91
78
  return {
92
79
  schema: ACTOR_TRACE_SCHEMA,
@@ -113,17 +100,13 @@ export function buildTerminalActorTrace(args) {
113
100
  ...(args.tokenUsage ? { tokenUsage: args.tokenUsage } : {}),
114
101
  counts: {
115
102
  commands: args.commandLog.length,
116
- // Unlike the legacy transcript message/actions counts, this establishes
117
- // actual runtime item activity. Stderr and bootstrap commands never count.
118
- // Read the full retained stdout: its early items may no longer be in the tail.
119
- runtimeParticipantItems: countTerminalParticipantItems(normalizeLocalActorTranscript(args.terminalEvents
120
- .filter((event) => event.stream === "stdout")
121
- .map((event) => event.chunk)
122
- .join(""))),
123
- // actions == executed commands; messages == 1 when the agent produced any output. The
124
- // no-engagement guard (verify/actor.ts) reads these: a real run bumps them, a no-op is caught.
103
+ // Unlike the actions count, this establishes actual runtime item activity. Stderr and
104
+ // bootstrap commands never count.
105
+ runtimeParticipantItems: args.participant.participantItems,
106
+ // actions == executed commands, so the launcher command alone keeps the no-engagement guard
107
+ // (verify/actor.ts) satisfied; messages == the agent_message items in the stream.
125
108
  actions: args.commandLog.length,
126
- messages: args.terminalEvents.length > 0 ? 1 : 0,
109
+ messages: args.participant.messages,
127
110
  terminalEvents: args.terminalEvents.length,
128
111
  },
129
112
  items,
@@ -132,41 +115,3 @@ export function buildTerminalActorTrace(args) {
132
115
  : TERMINAL_AGENT_CAPABILITIES,
133
116
  };
134
117
  }
135
- const itemEvents = new Set(["item.started", "item.updated", "item.completed"]);
136
- const nonempty = (value) => typeof value === "string" && value.trim().length > 0;
137
- const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
138
- /** Count distinct participant items in the retained Codex JSON stdout stream.
139
- * The caller supplies stdout only, after transport reconciliation and redaction.
140
- * Lifecycle, usage, launcher diagnostics, and nested command output are not activity.
141
- * Zero means no recognized item was retained, not that the participant succeeded.
142
- */
143
- export function countTerminalParticipantItems(stdout) {
144
- const ids = new Set();
145
- for (const line of stdout.split("\n")) {
146
- let event;
147
- try {
148
- event = JSON.parse(line);
149
- }
150
- catch {
151
- continue;
152
- }
153
- if (!object(event) ||
154
- typeof event.type !== "string" ||
155
- !itemEvents.has(event.type) ||
156
- !object(event.item))
157
- continue;
158
- const item = event.item;
159
- if (!nonempty(item.id))
160
- continue;
161
- const active = ((item.type === "agent_message" || item.type === "reasoning") && nonempty(item.text)) ||
162
- (item.type === "command_execution" && nonempty(item.command)) ||
163
- (item.type === "web_search" &&
164
- (nonempty(item.query) || (object(item.action) && nonempty(item.action.type)))) ||
165
- (item.type === "file_change" &&
166
- Array.isArray(item.changes) &&
167
- item.changes.some((change) => object(change) && nonempty(change.path) && nonempty(change.kind)));
168
- if (active)
169
- ids.add(item.id);
170
- }
171
- return ids.size;
172
- }