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
@@ -1,4 +1,3 @@
1
- import {} from "../../run/status.js";
2
1
  import { redactText } from "../../evidence/redaction.js";
3
2
  import { participantAssignment } from "../../lab/participant-assignment.js";
4
3
  import { REVIEW_SCHEMA, bundleArtifacts, bundleHead, } from "../../run/bundle.js";
@@ -9,21 +8,21 @@ import { describeMeasuredSpend, noSpendLineMeasured, noSpendNotEstablished } fro
9
8
  /**
10
9
  * Project the terminal-product lab run into a humanish.run-bundle.v1 (no schema change — a new
11
10
  * producer only). DRY-RUN: a contract bundle. The terminal stream is a contract placeholder
12
- * (stdin disabled, no captured tail — honest: nothing ran), the subject is declared UNPINNED, and
11
+ * (stdin disabled, no captured tail, because nothing ran), the subject is declared unpinned, and
13
12
  * the caps/policies/runtime-auth declarations are recorded without pretending that live ledgers
14
13
  * exist. The shipped live builder fills the same evidence contract. Exported for tests.
15
14
  */
16
15
  export function buildTerminalProductBundle(args) {
17
16
  const reason = "Contract bundle only: dry-run declared the terminal-product study contract without creating an E2B sandbox, injecting any key, or spending. This run did not execute an agent or prove live behavior.";
18
- // The terminal stream is a CONTRACT PLACEHOLDER on the dry-run path: stdin is disabled and no
19
- // exec output was captured, so the tail is empty and transport stays "snapshot" — NOT "pty"
17
+ // The terminal stream is a contract placeholder on the dry-run path: stdin is disabled and no
18
+ // exec output was captured, so the tail is empty and transport stays "snapshot", never "pty"
20
19
  // (captured non-interactive exec output is never an interactive PTY; invariant 6 + the PTY
21
20
  // ruling). The shipped live builder fills terminal.tail from redacted exec-stream capture.
22
21
  const { simulation, stream } = terminalParticipant(args, {
23
22
  status: "contract_proof_only",
24
23
  reason,
25
24
  summary: `Contract participant for the terminal agent (${args.actorId}) studying ${args.productName} from public surfaces.`,
26
- updatedAt: args.createdAt,
25
+ updatedAt: args.run.createdAt,
27
26
  stdin: args.stdin,
28
27
  tail: "",
29
28
  artifacts: [
@@ -36,40 +35,40 @@ export function buildTerminalProductBundle(args) {
36
35
  const events = [
37
36
  {
38
37
  id: "event-000-created",
39
- at: args.createdAt,
38
+ at: args.run.createdAt,
40
39
  level: "info",
41
40
  type: "terminal-lab.run.created",
42
41
  message: `Created terminal-product lab run for ${args.labId} (actor ${args.actorId}, product ${args.productName}).`,
43
42
  },
44
43
  participantEvent(TERMINAL_IDS, {
45
44
  id: "event-001-subject",
46
- at: args.createdAt,
45
+ at: args.run.createdAt,
47
46
  level: "info",
48
47
  type: "terminal-lab.subject.declared",
49
- // Invariant 5: provenance recorded or its absence DECLARED. The agent drives PUBLIC surfaces,
50
- // not a clone, so the subject provenance is explicitly UNPINNED; evidence binds to the
48
+ // Invariant 5: provenance recorded or its absence declared. The agent drives public surfaces
49
+ // and nothing is cloned, so the subject provenance is explicitly unpinned; evidence binds to the
51
50
  // composed-prompt digest. Public surfaces are recorded (they are public by declaration).
52
51
  message: `Subject product declared: ${args.productName}; public surfaces: ${args.publicSurfaces.join(", ")}. The lab did not provision/clone the product — subject provenance is UNPINNED (a public-surface study cannot be commit-pinned); evidence binds to the composed-prompt digest ${args.persona.promptDigest}.`,
53
52
  }),
54
53
  participantEvent(TERMINAL_IDS, {
55
54
  id: "event-002-credentials",
56
- at: args.createdAt,
55
+ at: args.run.createdAt,
57
56
  level: "info",
58
57
  type: "terminal-lab.credentials.declared",
59
- // Names-only evidence (invariant 1): the runtime-auth CHANNEL is declared; no value is ever
58
+ // Names-only evidence (invariant 1): the runtime-auth channel is declared; no value is ever
60
59
  // recorded. The deny-by-default policies are recorded so the credential posture is auditable.
61
60
  message: `Runtime auth channel: ${args.runtimeAuth ?? "none declared"} (names only; values never persist; the live engine applies the selected key placement, while this dry-run performs no injection). Credential policies (deny-by-default): allowPrivateRepoAccess=${args.policies.allowPrivateRepoAccess}, allowProviderCredentials=${args.policies.allowProviderCredentials}, allowPaymentCredentials=${args.policies.allowPaymentCredentials}, allowGitHubMutation=${args.policies.allowGitHubMutation}.`,
62
61
  }),
63
62
  participantEvent(TERMINAL_IDS, {
64
63
  id: "event-003-caps",
65
- at: args.createdAt,
64
+ at: args.run.createdAt,
66
65
  level: "info",
67
66
  type: "terminal-lab.caps.declared",
68
67
  message: `Spend/job/time caps: ${capsText}. A live run never exercises the runtime key without a fail-closed cap; its no-spend proof is derived from the persisted cost ledger. This dry-run spends $0 by mechanism.`,
69
68
  }),
70
69
  participantEvent(TERMINAL_IDS, {
71
70
  id: "event-004-contract",
72
- at: args.createdAt,
71
+ at: args.run.createdAt,
73
72
  level: "info",
74
73
  type: "terminal-lab.contract.ready",
75
74
  message: "Dry-run contract bundle ready. Switch scenario.mode to live with the required runtime auth and caps to exercise the in-sandbox agent route, captured exec stream, and declared runtime-auth placement.",
@@ -85,10 +84,9 @@ export function buildTerminalProductBundle(args) {
85
84
  ],
86
85
  };
87
86
  return terminalRunBundle(args, {
88
- mode: args.dryRun ? "dry-run" : "live",
89
87
  lifecycle: [
90
88
  {
91
- at: args.createdAt,
89
+ at: args.run.createdAt,
92
90
  event: "terminal-lab.run.created",
93
91
  message: `Created terminal-product lab run with one in-sandbox agent participant (actor ${args.actorId}, product ${args.productName}).`,
94
92
  },
@@ -101,7 +99,7 @@ export function buildTerminalProductBundle(args) {
101
99
  });
102
100
  }
103
101
  /**
104
- * Build the LIVE terminal-product run bundle (mode "live") from the captured session: the actor
102
+ * Build the live terminal-product run bundle (mode "live") from the captured session: the actor
105
103
  * trace seam (stream.actor = trace), the substrate-lifecycle events, the terminal stream with the
106
104
  * redacted transcript tail, and references to the written evidence artifacts (terminal event
107
105
  * stream, transcript, ledgers, actor trace). verifyRun's terminal-product check (gated on
@@ -115,10 +113,10 @@ export function buildLiveTerminalProductBundle(args) {
115
113
  : args.trace.status === "timed_out"
116
114
  ? "timed_out"
117
115
  : "failed";
118
- const messageItem = args.trace.items.find((item) => item.kind === "message");
119
- const tail = (messageItem?.text ?? args.trace.reason).slice(0, 2000);
116
+ const commandItem = args.trace.items.find((item) => item.kind === "command");
117
+ const tail = (commandItem?.command?.outputTail || args.trace.reason).slice(0, 2000);
120
118
  // transport "snapshot": the persisted tail is a redacted snapshot of the captured exec output,
121
- // NOT an interactive PTY (stdin disabled). The actor trace seam carries the structured evidence.
119
+ // never an interactive PTY (stdin disabled). The actor trace seam carries the structured evidence.
122
120
  const { simulation, stream } = terminalParticipant(args, {
123
121
  status: recordStatus,
124
122
  reason: args.sessionReason,
@@ -149,9 +147,9 @@ export function buildLiveTerminalProductBundle(args) {
149
147
  type: record.event,
150
148
  message: record.message,
151
149
  }));
152
- // Surface the no-spend proof as a first-class bundle event so the Observer/review can SHOW it.
153
- // It is DERIVED from the cost ledger (never asserted): it lists the known-zero lines it vouches
154
- // for AND the unmeasured (null) lines it explicitly cannot vouch for.
150
+ // Surface the no-spend proof as a first-class bundle event so the Observer/review can show it.
151
+ // It is derived from the cost ledger (never asserted): it lists the known-zero lines it vouches
152
+ // for and the unmeasured (null) lines it explicitly cannot vouch for.
155
153
  const noSpend = args.ledgers.noSpendProof;
156
154
  lifecycleEvents.push(participantEvent(TERMINAL_IDS, {
157
155
  id: "event-cost-no-spend-proof",
@@ -169,7 +167,7 @@ export function buildLiveTerminalProductBundle(args) {
169
167
  ? []
170
168
  : [`Agent session ended ${args.trace.status}: ${args.sessionReason}`]),
171
169
  ...(args.capFailure === undefined ? [] : [args.capFailure]),
172
- // Honesty gap: the no-spend proof always declares which spend lines it could NOT measure, so a
170
+ // Honesty gap: the no-spend proof always declares which spend lines it could not measure, so a
173
171
  // green run never silently over-claims a fully-proven $0.
174
172
  ...(noSpend.unmeasuredLines.length > 0
175
173
  ? [
@@ -179,7 +177,6 @@ export function buildLiveTerminalProductBundle(args) {
179
177
  ],
180
178
  };
181
179
  return terminalRunBundle(args, {
182
- mode: "live",
183
180
  lifecycle: args.ledgers.lifecycle.map((record) => ({
184
181
  at: record.at,
185
182
  event: record.event,
@@ -206,7 +203,7 @@ function terminalParticipant(args, session) {
206
203
  progress: 100,
207
204
  currentStep: session.reason,
208
205
  summary: session.summary,
209
- startedAt: args.createdAt,
206
+ startedAt: args.run.createdAt,
210
207
  updatedAt: session.updatedAt,
211
208
  });
212
209
  const stream = participantStream(TERMINAL_IDS, {
@@ -232,17 +229,10 @@ function terminalParticipant(args, session) {
232
229
  });
233
230
  return { simulation, stream };
234
231
  }
235
- /** The run bundle around the lane: the fields both builders fill the same way. */
232
+ /** The run bundle around the terminal session: the fields both builders fill the same way. */
236
233
  function terminalRunBundle(args, parts) {
237
234
  return {
238
- ...bundleHead({
239
- runId: args.runId,
240
- mode: parts.mode,
241
- participants: 1,
242
- createdAt: args.createdAt,
243
- ...(args.lab === undefined ? {} : { lab: args.lab }),
244
- source: args.source,
245
- }),
235
+ ...bundleHead(args.run, { participants: 1, source: args.source }),
246
236
  persona: {
247
237
  id: args.persona.id,
248
238
  name: `Autonomous terminal agent (${args.persona.id})`,
@@ -22,8 +22,8 @@ export declare function buildRuntimeAuth(args: {
22
22
  message: string;
23
23
  };
24
24
  /**
25
- * Build the sandbox metadata from a POSITIVE ALLOWLIST (safety contract item 6). This is the ONLY
26
- * way metadata is set on the terminal lane — it carries solely non-secret labels and rejects any
25
+ * Build the sandbox metadata from a positive allowlist (safety contract item 6). This is the only
26
+ * way metadata is set on the terminal route — it carries solely non-secret labels and rejects any
27
27
  * value that is not a plain short label. A verifier check asserts the persisted metadata has no
28
28
  * prompt/token/secret shapes; this builder makes that true by construction.
29
29
  */
@@ -7,22 +7,22 @@ import { TERMINAL_PRODUCT_LAB_PROVIDER_METADATA } from "./types.js";
7
7
  * credential is forwarded. The real value must never be logged or persisted in either mode.
8
8
  */
9
9
  export function buildRuntimeAuth(args) {
10
- // The "openai-env" channel accepts CODEX_API_KEY or OPENAI_API_KEY as the runtime key SOURCE
10
+ // The "openai-env" channel accepts CODEX_API_KEY or OPENAI_API_KEY as the runtime key source
11
11
  // name, read in this preference order. CODEX_API_KEY is preferred: the official Codex docs
12
- // (developers.openai.com/codex/noninteractive) document it as the channel for a SINGLE codex exec
13
- // invocation, which is exactly this lane's shape (no persisted auth.json/CODEX_HOME, per-command
12
+ // (developers.openai.com/codex/noninteractive) document it as the channel for a single codex exec
13
+ // invocation, which is exactly this route's shape (no persisted auth.json/CODEX_HOME, per-command
14
14
  // envs only). A dated in-repo receipt
15
15
  // (docs/goals/humanish-recursive-proof-critical-point/receipts/actor-required-attempt.md) shows a
16
16
  // job-wide OPENAI_API_KEY alone failing bearer auth for this same pinned-exec pattern. When the
17
- // operator only exported OPENAI_API_KEY, its value is ALSO injected under CODEX_API_KEY below, so
17
+ // operator only exported OPENAI_API_KEY, its value is also injected under CODEX_API_KEY below, so
18
18
  // the documented exec auth channel is always populated regardless of which name the operator
19
- // used. The ALLOWLIST is exactly these two names; everything else is denied by construction.
19
+ // used. The allowlist is exactly these two names; everything else is denied by construction.
20
20
  const ALLOWED_RUNTIME_KEY_NAMES = ["CODEX_API_KEY", "OPENAI_API_KEY"];
21
- // Tripwire (safety contract item 4): if a FUTURE widening of ALLOWED_RUNTIME_KEY_NAMES ever
21
+ // Tripwire (safety contract item 4): if a future widening of ALLOWED_RUNTIME_KEY_NAMES ever
22
22
  // added a clearly-non-runtime credential (a GitHub/payment/deploy/db secret), fail closed. The
23
- // generic `*_KEY` shape is deliberately NOT a tripwire here, since a runtime key legitimately
23
+ // generic `*_KEY` shape is deliberately left out of the tripwire, since a runtime key legitimately
24
24
  // ends in _KEY (CODEX_API_KEY/OPENAI_API_KEY), so testing it against the generic shape would
25
- // false-positive on the very key this lane exists to inject. The positive allowlist itself is
25
+ // false-positive on the very key this route exists to inject. The positive allowlist itself is
26
26
  // the real boundary: the command env is built from exactly these names and nothing else (so
27
27
  // GITHUB_TOKEN/payment/db keys present in the operator env are never forwarded, proven by the
28
28
  // deterministic test).
@@ -42,9 +42,9 @@ export function buildRuntimeAuth(args) {
42
42
  };
43
43
  }
44
44
  const keyValue = args.env[keyName];
45
- // The command-scoped env is the ALLOWLIST: exactly the runtime key name(s), nothing else. No
45
+ // The command-scoped env is the allowlist: exactly the runtime key name(s). No
46
46
  // GITHUB_TOKEN/GH_TOKEN, no payment/deploy/db/media key, excluded by construction. When the
47
- // SOURCE was OPENAI_API_KEY, the SAME value is also injected as CODEX_API_KEY so codex exec's
47
+ // source was OPENAI_API_KEY, the same value is also injected as CODEX_API_KEY so codex exec's
48
48
  // documented single-invocation auth channel is populated either way (see the comment above).
49
49
  const mode = args.runtimeAuth ?? "openai-env";
50
50
  const envs = mode === "openai-egress"
@@ -62,11 +62,11 @@ export function buildRuntimeAuth(args) {
62
62
  keyValue,
63
63
  };
64
64
  }
65
- // Clearly-non-runtime credential NAME shapes. Used as the runtime-key allowlist tripwire (a
66
- // runtime key must never be one of these). Deliberately EXCLUDES the generic `*_KEY` shape: the
67
- // runtime key this lane injects (CODEX_API_KEY/OPENAI_API_KEY) legitimately ends in _KEY, so the
65
+ // Clearly-non-runtime credential name shapes. Used as the runtime-key allowlist tripwire (a
66
+ // runtime key must never be one of these). Deliberately excludes the generic `*_KEY` shape: the
67
+ // runtime key this route injects (CODEX_API_KEY/OPENAI_API_KEY) legitimately ends in _KEY, so the
68
68
  // generic shape would false-positive on it. The positive allowlist, not a denylist, is what
69
- // keeps every OTHER operator-env credential (GitHub/payment/deploy/db/media keys) out of the
69
+ // keeps every other operator-env credential (GitHub/payment/deploy/db/media keys) out of the
70
70
  // sandbox: the command env is built from exactly the allowlisted runtime key and nothing else.
71
71
  const NON_RUNTIME_CREDENTIAL_NAME_PATTERNS = [
72
72
  /^GITHUB_TOKEN$/i,
@@ -84,8 +84,8 @@ function isNonRuntimeCredentialName(name) {
84
84
  return NON_RUNTIME_CREDENTIAL_NAME_PATTERNS.some((pattern) => pattern.test(name));
85
85
  }
86
86
  /**
87
- * Build the sandbox metadata from a POSITIVE ALLOWLIST (safety contract item 6). This is the ONLY
88
- * way metadata is set on the terminal lane — it carries solely non-secret labels and rejects any
87
+ * Build the sandbox metadata from a positive allowlist (safety contract item 6). This is the only
88
+ * way metadata is set on the terminal route — it carries solely non-secret labels and rejects any
89
89
  * value that is not a plain short label. A verifier check asserts the persisted metadata has no
90
90
  * prompt/token/secret shapes; this builder makes that true by construction.
91
91
  */
@@ -15,7 +15,7 @@ export declare function runDryTerminalLab(args: {
15
15
  failed: RunLiveTerminalSessionArgs["failed"];
16
16
  scope: RunScope;
17
17
  }): Promise<TerminalProductLabResult>;
18
- /** Compose the full prompt the agent would run. Bound to evidence by DIGEST only. */
18
+ /** Compose the full prompt the agent would run. Bound to evidence by digest only. */
19
19
  export declare function composePrompt(args: {
20
20
  mission: string;
21
21
  personaLine: string;
@@ -17,11 +17,10 @@ import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
17
17
  export async function runDryTerminalLab(args) {
18
18
  const { plan, input, cwd, warnings, failed, scope } = args;
19
19
  const { product } = plan;
20
- const hooks = input.hooks ?? {};
21
20
  const { evidenceMission, physicalCwd, persona } = await prepareDryPersona({
22
21
  plan,
23
22
  cwd,
24
- env: hooks.env ?? process.env,
23
+ env: input.env ?? process.env,
25
24
  warnings,
26
25
  });
27
26
  const started = await scope.startRun({
@@ -31,7 +30,7 @@ export async function runDryTerminalLab(args) {
31
30
  mode: "dry-run",
32
31
  lab: plan.lab,
33
32
  renderReview: renderTerminalReviewMarkdown,
34
- observer: { open: input.open === true, render: hooks.renderObserverFn },
33
+ observer: { open: input.open === true, render: input.deps?.renderObserver },
35
34
  });
36
35
  if (!started.ok)
37
36
  return failed(started.code, started.message);
@@ -46,9 +45,8 @@ export async function runDryTerminalLab(args) {
46
45
  const policies = plan.residual.policies;
47
46
  const judgment = judgeTerminal({ dryRun: true, participant: undefined });
48
47
  const bundle = buildTerminalProductBundle({
49
- ...(plan.lab === undefined ? {} : { lab: plan.lab }),
48
+ run,
50
49
  actorId: plan.actor,
51
- createdAt,
52
50
  dryRun: true,
53
51
  labId: plan.labId,
54
52
  ...(plan.title ? { labTitle: plan.title } : {}),
@@ -65,7 +63,6 @@ export async function runDryTerminalLab(args) {
65
63
  allowPaymentCredentials: policies?.allowPaymentCredentials ?? false,
66
64
  allowGitHubMutation: policies?.allowGitHubMutation ?? false,
67
65
  },
68
- runId,
69
66
  source,
70
67
  verdict: judgment.verdict,
71
68
  });
@@ -118,9 +115,9 @@ async function prepareDryPersona(args) {
118
115
  .filter((value) => value.length >= 4);
119
116
  const evidenceMission = participantAssignment({ mission }, scrubLiterals(knownSecretValues)).mission;
120
117
  const terminalPersona = await resolveTerminalPersona({ plan, cwd, warnings });
121
- // The composed prompt = mission + persona + public-surface manifest. Only the AUTHOR mission
118
+ // The composed prompt = mission + persona + public-surface manifest. Only the author mission
122
119
  // goes plaintext into evidence (it is public-safe committed lab text); the full composed prompt
123
- // is recorded as a DIGEST (the safety contract's mission ruling).
120
+ // is recorded as a digest (the safety contract's mission ruling).
124
121
  const composedPrompt = composePrompt({
125
122
  mission,
126
123
  personaLine: terminalPersona.personaLine,
@@ -133,7 +130,7 @@ async function prepareDryPersona(args) {
133
130
  }
134
131
  /** The declared runtime provenance as a dry-run event; nothing is observed without a sandbox. */
135
132
  function runtimeDeclaredEvent(runtime, createdAt) {
136
- const { version, model, reasoningEffort } = runtime;
133
+ const { version, model, modelSource, reasoningEffort } = runtime;
137
134
  return {
138
135
  id: "event-terminal-runtime-declared",
139
136
  at: createdAt,
@@ -141,12 +138,13 @@ function runtimeDeclaredEvent(runtime, createdAt) {
141
138
  type: "terminal-lab.runtime.declared",
142
139
  message: redactText(JSON.stringify(declaredRuntimeProvenance({
143
140
  ...(version === undefined ? {} : { version }),
144
- ...(model === undefined ? {} : { model }),
141
+ model,
142
+ modelSource,
145
143
  ...(reasoningEffort === undefined ? {} : { reasoningEffort }),
146
144
  }))),
147
145
  };
148
146
  }
149
- /** Compose the full prompt the agent would run. Bound to evidence by DIGEST only. */
147
+ /** Compose the full prompt the agent would run. Bound to evidence by digest only. */
150
148
  export function composePrompt(args) {
151
149
  return [
152
150
  args.personaLine,
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Does this environment declare a UTF-8 locale? The POSIX variables are checked in the order the C
3
- * library resolves them (LC_ALL overrides LC_CTYPE overrides LANG).
3
+ * library resolves them (`LC_ALL` overrides `LC_CTYPE` overrides `LANG`).
4
4
  *
5
5
  * Windows terminals declare none of these and are handled as UTF-8: modern Windows Terminal and
6
6
  * PowerShell render it, and the failure this guards against is a Unix locale that says C/POSIX.
@@ -1,6 +1,6 @@
1
1
  // Whether this terminal can render the characters we write to it.
2
2
  //
3
- // FOUND BY A PARTICIPANT, not by us (labs/tui-self-study.yaml): a computer-use participant sitting
3
+ // A participant found this (labs/tui-self-study.yaml): a computer-use participant sitting
4
4
  // at a stock desktop ran `humanish` and read back `humanish ��� run realistic synthetic personas`.
5
5
  // The em dash is three bytes of UTF-8, and a terminal whose locale is not UTF-8 renders each byte
6
6
  // as a replacement glyph. Every ASCII character on the same screen was fine, which is exactly the
@@ -12,7 +12,7 @@
12
12
  const UTF8 = /utf-?8/i;
13
13
  /**
14
14
  * Does this environment declare a UTF-8 locale? The POSIX variables are checked in the order the C
15
- * library resolves them (LC_ALL overrides LC_CTYPE overrides LANG).
15
+ * library resolves them (`LC_ALL` overrides `LC_CTYPE` overrides `LANG`).
16
16
  *
17
17
  * Windows terminals declare none of these and are handled as UTF-8: modern Windows Terminal and
18
18
  * PowerShell render it, and the failure this guards against is a Unix locale that says C/POSIX.
@@ -3,10 +3,10 @@ import type { LabScenarioCaps } from "../../lab/types.js";
3
3
  import { type CostCategory } from "../../run/terminal-contract.js";
4
4
  import type { CostLine, NoSpendProof, TerminalCostLedger } from "./types.js";
5
5
  /**
6
- * Build the spend ledger from the captured session. THE NULL DISCIPLINE (issue #154):
6
+ * Build the spend ledger from the captured session. The null discipline (issue #154):
7
7
  * - The `provider` line is populated from the actor trace's tokenUsage.costUsd when the trace
8
- * CARRIES it (a measured value, incl. a measured 0). When the trace carries NO costUsd, the
9
- * provider line is `null` = NOT MEASURED (never guessed to 0 just because no-spend was intended).
8
+ * carries it (a measured value, incl. a measured 0). When the trace carries no costUsd, the
9
+ * provider line is `null` = not measured (never guessed to 0 just because no-spend was intended).
10
10
  * - product/media/payment are `null` by default: core has no signal for those categories; an
11
11
  * adapter may provide one through the shipped costProbe seam.
12
12
  * `injectedLines` lets a test or adapter supply known spend for a category,
@@ -31,13 +31,13 @@ export declare function noSpendNotEstablished(maxUsd: number): string;
31
31
  * an all-null ledger for a proven $0.
32
32
  */
33
33
  export declare function describeMeasuredSpend(ledger: TerminalCostLedger, tokenUsage?: ActorTokenUsage): string;
34
- /** Derive the no-spend proof from the ledger. It is HONEST: it vouches for known-zero lines and
34
+ /** Derive the no-spend proof from the ledger. It vouches for known-zero lines and
35
35
  * explicitly lists the unmeasured (null) lines it cannot vouch for — never claiming zero on null. */
36
36
  export declare function buildNoSpendProof(ledger: TerminalCostLedger, maxUsd: number | null, tokenUsage?: ActorTokenUsage): NoSpendProof;
37
37
  /**
38
- * Full caps enforcement (fail-closed, not advisory). Returns a structured violation when a KNOWN
38
+ * Fail-closed caps enforcement. Returns a structured violation when a known
39
39
  * (measured) spend line exceeds maxUsd, or a known billable-job count exceeds maxJobs. Unknowns
40
- * (`null`) NEVER trip the cap (we cannot claim a violation we did not measure) — but they also never
40
+ * (`null`) never trip the cap (we cannot claim a violation we did not measure), and they also never
41
41
  * grant a green pass: the no-spend proof reports them as unmeasured. maxMinutes is wall-clock and is
42
42
  * enforced separately (runWithWallClock); it is not a ledger-derived cap.
43
43
  */
@@ -2,10 +2,10 @@ import { describeTokenUsage } from "./token-usage.js";
2
2
  import { round6 } from "../../run/pricing.js";
3
3
  import { COST_CATEGORIES } from "../../run/terminal-contract.js";
4
4
  /**
5
- * Build the spend ledger from the captured session. THE NULL DISCIPLINE (issue #154):
5
+ * Build the spend ledger from the captured session. The null discipline (issue #154):
6
6
  * - The `provider` line is populated from the actor trace's tokenUsage.costUsd when the trace
7
- * CARRIES it (a measured value, incl. a measured 0). When the trace carries NO costUsd, the
8
- * provider line is `null` = NOT MEASURED (never guessed to 0 just because no-spend was intended).
7
+ * carries it (a measured value, incl. a measured 0). When the trace carries no costUsd, the
8
+ * provider line is `null` = not measured (never guessed to 0 just because no-spend was intended).
9
9
  * - product/media/payment are `null` by default: core has no signal for those categories; an
10
10
  * adapter may provide one through the shipped costProbe seam.
11
11
  * `injectedLines` lets a test or adapter supply known spend for a category,
@@ -47,7 +47,7 @@ export function buildCostLedger(args) {
47
47
  payment: args.injectedLines?.payment ?? unmeasured("payment"),
48
48
  provider: args.injectedLines?.provider ?? providerLine,
49
49
  };
50
- // knownTotalUsd sums ONLY the non-null lines. A null line contributes NOTHING — it is never
50
+ // knownTotalUsd sums only the non-null lines. A null line contributes nothing and is never
51
51
  // coerced to 0 (that would let an unmeasured category masquerade as a measured zero).
52
52
  let knownTotalUsd = 0;
53
53
  let fullyMeasured = true;
@@ -98,7 +98,7 @@ export function describeMeasuredSpend(ledger, tokenUsage) {
98
98
  .filter((part) => part.length > 0)
99
99
  .join(" ");
100
100
  }
101
- /** Derive the no-spend proof from the ledger. It is HONEST: it vouches for known-zero lines and
101
+ /** Derive the no-spend proof from the ledger. It vouches for known-zero lines and
102
102
  * explicitly lists the unmeasured (null) lines it cannot vouch for — never claiming zero on null. */
103
103
  export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
104
104
  const knownZeroLines = [];
@@ -113,8 +113,8 @@ export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
113
113
  else
114
114
  knownNonZeroLines.push(category);
115
115
  }
116
- // satisfied only when every KNOWN line is within the cap (for a no-spend run, maxUsd 0 => every
117
- // known line must be exactly 0). Unmeasured lines do NOT make it satisfied — they are reported
116
+ // satisfied only when every known line is within the cap (for a no-spend run, maxUsd 0 => every
117
+ // known line must be exactly 0). Unmeasured lines never make it satisfied; they are reported
118
118
  // separately as the proof's honest blind spot.
119
119
  const cap = maxUsd ?? 0;
120
120
  const satisfied = knownNonZeroLines.length === 0 && ledger.knownTotalUsd <= cap;
@@ -138,9 +138,9 @@ export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
138
138
  };
139
139
  }
140
140
  /**
141
- * Full caps enforcement (fail-closed, not advisory). Returns a structured violation when a KNOWN
141
+ * Fail-closed caps enforcement. Returns a structured violation when a known
142
142
  * (measured) spend line exceeds maxUsd, or a known billable-job count exceeds maxJobs. Unknowns
143
- * (`null`) NEVER trip the cap (we cannot claim a violation we did not measure) — but they also never
143
+ * (`null`) never trip the cap (we cannot claim a violation we did not measure), and they also never
144
144
  * grant a green pass: the no-spend proof reports them as unmeasured. maxMinutes is wall-clock and is
145
145
  * enforced separately (runWithWallClock); it is not a ledger-derived cap.
146
146
  */
@@ -2,7 +2,7 @@ import type { ActorPersonaRef } from "../../actors/contract.js";
2
2
  import type { RunBundle } from "../../run/bundle.js";
3
3
  import type { RunScope } from "../../run/run.js";
4
4
  import type { LiveSandboxInputs, LiveTerminalSandbox } from "./live-sandbox.js";
5
- import type { RunLiveTerminalSessionArgs, TerminalProductLabHooks, TerminalProductLabResult } from "./types.js";
5
+ import type { RunLiveTerminalSessionArgs, TerminalProductLabResult } from "./types.js";
6
6
  type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
7
7
  ok: true;
8
8
  }>["run"];
@@ -11,7 +11,6 @@ export interface LiveFinishInputs {
11
11
  plan: RunLiveTerminalSessionArgs["plan"];
12
12
  input: RunLiveTerminalSessionArgs["input"];
13
13
  cwd: string;
14
- hooks: TerminalProductLabHooks;
15
14
  sanitize: (text: string) => string;
16
15
  nowIso: () => string;
17
16
  knownSecretValues: string[];
@@ -3,7 +3,7 @@
3
3
  import { buildRunCostSummary } from "../../run/cost-summary.js";
4
4
  import { writeContainedOutputFile } from "../../run/contained-output.js";
5
5
  import { validatePreparedRunArtifactPaths, } from "../../run/paths.js";
6
- import { estimateActorCost } from "../../run/pricing.js";
6
+ import { estimateAggregatedTurnCost } from "../../run/pricing.js";
7
7
  import { normalizeLocalActorTranscript, TERMINAL_EVENTS_ARTIFACT, TERMINAL_LEDGERS_ARTIFACT, TERMINAL_TRANSCRIPT_ARTIFACT, } from "../../run/terminal-contract.js";
8
8
  import { applyAdapterExtensionSeam } from "./adapter.js";
9
9
  import { buildLiveTerminalProductBundle } from "./bundle.js";
@@ -22,9 +22,9 @@ function buildLiveTrace(inputs) {
22
22
  // chunks before any transcript/trace/event artifact is persisted. Check both each stream and
23
23
  // the combined event order that the transcript uses; either view can assemble a split value.
24
24
  scrubSplitKnownValues(terminalEvents, knownSecretValues, discardedPrefixes);
25
- // Build the actor trace FIRST (the cost ledger reads its tokenUsage).
25
+ // Build the actor trace first (the cost ledger reads its tokenUsage).
26
26
  const normalizedTranscript = normalizeLocalActorTranscript(terminalEvents.map((e) => e.chunk).join(""));
27
- // Parsed from the FULL stream, not the tail: usage records arrive once per turn and the tail
27
+ // Parsed from the full stream: usage records arrive once per turn, and the tail
28
28
  // would drop all but the last (#531).
29
29
  const terminalTokenUsage = parseTerminalTokenUsage(normalizedTranscript);
30
30
  const trace = buildTerminalActorTrace({
@@ -39,27 +39,30 @@ function buildLiveTrace(inputs) {
39
39
  terminalEvents,
40
40
  commandLog,
41
41
  transcriptTail: tailOf(normalizedTranscript),
42
+ participant: inputs.recorder.participantText.finish(),
42
43
  runtimeAuth: runtimeEnv.mode,
43
44
  runtime,
44
45
  ...(terminalTokenUsage === undefined ? {} : { tokenUsage: terminalTokenUsage }),
45
46
  });
46
- // Codex tokens stay unpriced: the lane records its model as `codex`, which has no rate.
47
- trace.estimatedCost = estimateActorCost(trace.tokenUsage, trace.provider);
47
+ // Priced from the model the route passed to Codex. turn.completed sums a turn's requests, so the
48
+ // estimate uses base rates and says so.
49
+ trace.estimatedCost = estimateAggregatedTurnCost(trace.tokenUsage, runtime.requestedModel);
48
50
  return { normalizedTranscript, trace };
49
51
  }
50
52
  async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
51
- const { hooks, runtime, session } = inputs;
53
+ const { runtime, session } = inputs;
54
+ const costProbe = inputs.input.deps?.costProbe;
52
55
  const { caps } = inputs.plan;
53
56
  const { maxUsd } = caps;
54
57
  const runPaths = inputs.run.paths;
55
58
  const { recordLifecycle, lifecycle, commandLog, interventions, terminalEvents } = inputs.recorder;
56
59
  // --- Spend ledger + no-spend proof + full caps enforcement (fail-closed). ---
57
- // The cost ledger is DERIVED, with the null discipline: provider spend from the trace's
58
- // tokenUsage.costUsd when present (else null = NOT MEASURED), product/media/payment null by
59
- // default (core has no signal). The costProbe hook lets tests or adapters inject KNOWN
60
+ // The cost ledger is derived, with the null discipline: provider spend from the trace's
61
+ // tokenUsage.costUsd when present (else null = not measured), product/media/payment null by
62
+ // default (core has no signal). The costProbe hook lets tests or adapters inject known
60
63
  // spend to exercise the fail-closed cap without a real billable run.
61
- const injectedLines = hooks.costProbe?.(trace.tokenUsage?.costUsd === undefined ? {} : { tokenCostUsd: trace.tokenUsage.costUsd });
62
- if (hooks.costProbe)
64
+ const injectedLines = costProbe?.(trace.tokenUsage?.costUsd === undefined ? {} : { tokenCostUsd: trace.tokenUsage.costUsd });
65
+ if (costProbe)
63
66
  await validatePreparedRunArtifactPaths(runPaths);
64
67
  const cost = buildCostLedger({
65
68
  ...(trace.tokenUsage?.costUsd === undefined ? {} : { tokenCostUsd: trace.tokenUsage.costUsd }),
@@ -74,9 +77,9 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
74
77
  : `No-spend proof satisfied on the measured lines for maxUsd=${maxUsd ?? "null"}.`;
75
78
  const measuredSpend = describeMeasuredSpend(cost, trace.tokenUsage);
76
79
  recordLifecycle("terminal-lab.cost.measured", `Cost ledger: known total ${cost.knownTotalUsd} USD${cost.fullyMeasured ? " (fully measured)" : " (lower bound)"}.${measuredSpend.length > 0 ? ` ${measuredSpend}` : ""} ${proofVerdict}`);
77
- // FULL caps enforcement (fail-closed, NOT advisory): if a KNOWN spend line exceeds maxUsd (or a
80
+ // Fail-closed caps enforcement: if a known spend line exceeds maxUsd (or a
78
81
  // known job count exceeds maxJobs), the run fails closed — never a green result. Unknowns (null)
79
- // do NOT trip the cap (we cannot claim a violation we did not measure) but never grant a pass
82
+ // never trip the cap (we cannot claim a violation we did not measure) but never grant a pass
80
83
  // either (the no-spend proof reports them as unmeasured). maxMinutes is already wall-clock-
81
84
  // enforced above. A blown cap is an execution failure: the agent's own status stays the
82
85
  // verdict, and the result's ok is false.
@@ -91,7 +94,7 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
91
94
  runtime,
92
95
  lifecycle,
93
96
  commandLog,
94
- interventions, // ALWAYS present, ALWAYS empty while no assisted-input path ships.
97
+ interventions, // Always present, and always empty while no assisted-input path ships.
95
98
  cleanup: session.cleanup,
96
99
  cost,
97
100
  noSpendProof,
@@ -102,11 +105,11 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
102
105
  export async function finishLiveTerminalSession(inputs) {
103
106
  const { normalizedTranscript, trace } = buildLiveTrace(inputs);
104
107
  const { cost, noSpendProof, capFailure, ledgers } = await settleLiveLedgers(inputs, trace, normalizedTranscript);
105
- const { plan, input, cwd, hooks, sanitize } = inputs;
108
+ const { plan, input, cwd, sanitize } = inputs;
106
109
  const { product, caps } = plan;
107
110
  const policies = plan.residual.policies;
108
111
  const { runtimeEnv, persona, mission, run, source, warnings, session } = inputs;
109
- const { runId, createdAt, paths: runPaths } = run;
112
+ const { runId, paths: runPaths } = run;
110
113
  // One judgment, after a blown cap has overridden the session: the bundle's verdict (and so
111
114
  // status.json's outcome) and the result's ok both read it.
112
115
  const participant = terminalParticipantFacts(trace, session.error);
@@ -120,9 +123,8 @@ export async function finishLiveTerminalSession(inputs) {
120
123
  ...(desktops === undefined ? {} : { desktops }),
121
124
  });
122
125
  const bundle = buildLiveTerminalProductBundle({
123
- ...(plan.lab === undefined ? {} : { lab: plan.lab }),
126
+ run,
124
127
  actorId: plan.actor,
125
- createdAt,
126
128
  labId: plan.labId,
127
129
  ...(plan.title ? { labTitle: plan.title } : {}),
128
130
  mission: sanitize(mission),
@@ -138,7 +140,6 @@ export async function finishLiveTerminalSession(inputs) {
138
140
  allowPaymentCredentials: policies?.allowPaymentCredentials ?? false,
139
141
  allowGitHubMutation: policies?.allowGitHubMutation ?? false,
140
142
  },
141
- runId,
142
143
  source,
143
144
  trace,
144
145
  ledgers,
@@ -154,7 +155,7 @@ export async function finishLiveTerminalSession(inputs) {
154
155
  // through foldScorerFailures below. Adapter payloads pass the same scrub and redaction as the
155
156
  // rest of the bundle, and the bundle verifier checks them downstream.
156
157
  const scorer = await applyAdapterExtensionSeam({
157
- hooks,
158
+ scorer: input.scorer,
158
159
  bundle,
159
160
  trace,
160
161
  ledgers,
@@ -4,7 +4,8 @@ import type { RunScope } from "../../run/run.js";
4
4
  import type { buildRuntimeAuth, buildSandboxMetadata } from "./credentials.js";
5
5
  import type { createTerminalRecorder } from "./recorder.js";
6
6
  import { type declaredRuntimeProvenance } from "./runtime.js";
7
- import { type LiveTerminalPlan, type TerminalLedgers, type TerminalProductLabHooks } from "./types.js";
7
+ import { type LiveTerminalPlan, type TerminalLedgers } from "./types.js";
8
+ import type { LabDeps } from "../../lab/lab-deps.js";
8
9
  type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
9
10
  ok: true;
10
11
  }>["run"];
@@ -12,7 +13,7 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
12
13
  export interface LiveSandboxInputs {
13
14
  plan: LiveTerminalPlan;
14
15
  cwd: string;
15
- hooks: TerminalProductLabHooks;
16
+ deps: LabDeps;
16
17
  now: () => number;
17
18
  nowIso: () => string;
18
19
  sanitize: (text: string) => string;
@@ -47,6 +48,7 @@ export declare class LiveTerminalSandbox {
47
48
  private module;
48
49
  private allocation;
49
50
  private startupCleanup;
51
+ private startupCleanupDetail;
50
52
  private createdAtMs;
51
53
  private tornDownAtMs;
52
54
  private resources;