humanish 0.106.1 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/AGENTS.md +4 -4
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +14 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -8
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +30 -3
  16. package/dist/actors/codex/qualified-versions.js +50 -5
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +9 -7
  45. package/dist/actors/local-agent/cli.js +1 -1
  46. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  47. package/dist/actors/scripted-browser/journey.js +15 -4
  48. package/dist/actors/scripted-browser/steps.js +18 -0
  49. package/dist/actors/scripted-browser/types.d.ts +11 -1
  50. package/dist/actors/stop-conditions.js +1 -3
  51. package/dist/analysis/automatic-completion.d.ts +13 -8
  52. package/dist/analysis/automatic-completion.js +14 -8
  53. package/dist/analysis/automatic-config.d.ts +1 -1
  54. package/dist/analysis/automatic-config.js +2 -2
  55. package/dist/analysis/automatic.d.ts +10 -4
  56. package/dist/analysis/automatic.js +17 -13
  57. package/dist/analysis/diagnostics.d.ts +23 -0
  58. package/dist/analysis/diagnostics.js +112 -0
  59. package/dist/analysis/evidence-sources.js +2 -2
  60. package/dist/analysis/evidence.js +6 -6
  61. package/dist/analysis/execute.d.ts +7 -1
  62. package/dist/analysis/execute.js +39 -12
  63. package/dist/analysis/job.d.ts +8 -5
  64. package/dist/analysis/job.js +15 -14
  65. package/dist/analysis/load.d.ts +1 -1
  66. package/dist/analysis/load.js +5 -5
  67. package/dist/analysis/provider.d.ts +9 -1
  68. package/dist/analysis/restricted-codex.d.ts +2 -0
  69. package/dist/analysis/restricted-codex.js +10 -1
  70. package/dist/analysis/service.d.ts +2 -0
  71. package/dist/analysis/service.js +31 -12
  72. package/dist/analysis/sharing.d.ts +2 -2
  73. package/dist/analysis/sharing.js +5 -5
  74. package/dist/analysis/store-executions.d.ts +5 -5
  75. package/dist/analysis/store-executions.js +12 -12
  76. package/dist/analysis/store.d.ts +4 -4
  77. package/dist/analysis/store.js +13 -13
  78. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  79. package/dist/cli/commands/analysis-signals.js +4 -1
  80. package/dist/cli/commands/analyze.js +4 -2
  81. package/dist/cli/commands/comms.js +8 -1
  82. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  83. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  84. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  85. package/dist/cli/commands/lab-route-preview.js +3 -4
  86. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  87. package/dist/cli/commands/lab-route-run.js +6 -2
  88. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  89. package/dist/cli/commands/lab-route-scripted.js +0 -1
  90. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  91. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  92. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  93. package/dist/cli/commands/lab-route-terminal.js +0 -1
  94. package/dist/cli/commands/lab-run.js +76 -45
  95. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  96. package/dist/cli/commands/lab.js +12 -6
  97. package/dist/cli/commands/observe.js +22 -0
  98. package/dist/cli/commands/run-signals.d.ts +30 -0
  99. package/dist/cli/commands/run-signals.js +146 -0
  100. package/dist/cli/commands/runs.js +10 -8
  101. package/dist/cli/commands/watch.js +12 -10
  102. package/dist/cli/doctor.d.ts +3 -0
  103. package/dist/cli/doctor.js +10 -2
  104. package/dist/cli/io.d.ts +5 -4
  105. package/dist/cli/io.js +12 -8
  106. package/dist/cli/program.js +3 -3
  107. package/dist/cli/renamed-options.d.ts +11 -0
  108. package/dist/cli/renamed-options.js +18 -0
  109. package/dist/cli/telemetry.d.ts +2 -2
  110. package/dist/cli/telemetry.js +1 -1
  111. package/dist/comms/capture-surface.d.ts +1 -1
  112. package/dist/comms/catch-host.d.ts +1 -1
  113. package/dist/comms/connections.js +4 -4
  114. package/dist/comms/external-evidence.d.ts +27 -0
  115. package/dist/comms/external-evidence.js +93 -0
  116. package/dist/comms/lease-store.js +7 -7
  117. package/dist/comms/types.js +1 -1
  118. package/dist/evidence/browser-hygiene.d.ts +1 -1
  119. package/dist/evidence/browser-hygiene.js +1 -1
  120. package/dist/evidence/redaction.js +1 -1
  121. package/dist/evidence/secret-scrub.d.ts +9 -0
  122. package/dist/evidence/secret-scrub.js +96 -0
  123. package/dist/feedback/draft.js +7 -9
  124. package/dist/feedback/export-bundle.js +4 -4
  125. package/dist/feedback/export.js +9 -9
  126. package/dist/feedback/feedback.d.ts +1 -1
  127. package/dist/index.d.ts +3 -6
  128. package/dist/index.js +3 -6
  129. package/dist/keys/key-resolution.d.ts +3 -1
  130. package/dist/keys/key-resolution.js +18 -16
  131. package/dist/lab/adapter-extension.d.ts +28 -6
  132. package/dist/lab/adapter-extension.js +65 -126
  133. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  134. package/dist/lab/adapter-scorer-loader.js +24 -0
  135. package/dist/lab/composition-rules.js +20 -20
  136. package/dist/lab/config.js +28 -26
  137. package/dist/lab/device-presets.d.ts +2 -2
  138. package/dist/lab/discover.js +1 -3
  139. package/dist/lab/doctor.d.ts +44 -9
  140. package/dist/lab/doctor.js +149 -41
  141. package/dist/lab/init-plan.js +1 -3
  142. package/dist/lab/keys.js +1 -1
  143. package/dist/lab/lab-deps.d.ts +85 -0
  144. package/dist/lab/lab-deps.js +4 -0
  145. package/dist/lab/parse/actors.js +8 -7
  146. package/dist/lab/parse/comms.js +3 -2
  147. package/dist/lab/parse/execution.js +3 -2
  148. package/dist/lab/parse/subject-state.js +2 -1
  149. package/dist/lab/parse/subject.js +2 -1
  150. package/dist/lab/parse/values.d.ts +0 -1
  151. package/dist/lab/parse/values.js +0 -3
  152. package/dist/lab/persona-resolve.d.ts +3 -3
  153. package/dist/lab/persona-resolve.js +4 -4
  154. package/dist/lab/persona.js +1 -3
  155. package/dist/lab/plan-base.d.ts +0 -2
  156. package/dist/lab/plan-base.js +6 -4
  157. package/dist/lab/plan-participants.d.ts +5 -5
  158. package/dist/lab/plan-participants.js +2 -2
  159. package/dist/lab/plan-types.d.ts +22 -4
  160. package/dist/lab/plan.d.ts +3 -11
  161. package/dist/lab/plan.js +18 -42
  162. package/dist/lab/preflight-result.js +0 -2
  163. package/dist/lab/preflight.d.ts +0 -3
  164. package/dist/lab/preflight.js +1 -1
  165. package/dist/lab/requirements.d.ts +20 -0
  166. package/dist/lab/requirements.js +54 -0
  167. package/dist/lab/route-inputs.d.ts +23 -12
  168. package/dist/lab/route-inputs.js +48 -51
  169. package/dist/lab/routing.d.ts +19 -24
  170. package/dist/lab/routing.js +14 -47
  171. package/dist/lab/run-lab-events.d.ts +6 -11
  172. package/dist/lab/run-lab-events.js +3 -11
  173. package/dist/lab/run-lab-homes.d.ts +64 -0
  174. package/dist/lab/run-lab-homes.js +3 -0
  175. package/dist/lab/run-lab-options.d.ts +12 -66
  176. package/dist/lab/run-lab-options.js +45 -275
  177. package/dist/lab/summary.d.ts +9 -4
  178. package/dist/lab/summary.js +15 -8
  179. package/dist/lab/types.d.ts +132 -132
  180. package/dist/lab/validation.d.ts +15 -15
  181. package/dist/lab/validation.js +28 -28
  182. package/dist/lab/warnings.js +20 -19
  183. package/dist/observer/artifact.d.ts +1 -1
  184. package/dist/observer/artifact.js +3 -3
  185. package/dist/observer/data.js +2 -2
  186. package/dist/observer/render.js +2 -2
  187. package/dist/observer/run-routes.d.ts +1 -1
  188. package/dist/observer/run-routes.js +5 -5
  189. package/dist/observer/serve.d.ts +17 -0
  190. package/dist/observer/serve.js +34 -3
  191. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  192. package/dist/routes/computer-use/bundle-parts.js +10 -3
  193. package/dist/routes/computer-use/bundle.d.ts +4 -11
  194. package/dist/routes/computer-use/bundle.js +9 -15
  195. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  196. package/dist/routes/computer-use/diagnostics.js +1 -1
  197. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  198. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  199. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  200. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  201. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  202. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  203. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  204. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  205. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  206. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  207. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  208. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  209. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  210. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  211. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  212. package/dist/routes/computer-use/external-comms.js +19 -43
  213. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  214. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  215. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  216. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  217. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  218. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  219. package/dist/routes/computer-use/live-flush.js +19 -27
  220. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +12 -11
  221. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  222. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  223. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  224. package/dist/routes/computer-use/local-vm.js +39 -66
  225. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  226. package/dist/routes/computer-use/participant-desktop.js +5 -25
  227. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  228. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  229. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  230. package/dist/routes/computer-use/participant-facts.js +12 -1
  231. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  232. package/dist/routes/computer-use/participant-model.js +49 -25
  233. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  234. package/dist/routes/computer-use/participant-prompt.js +4 -4
  235. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  236. package/dist/routes/computer-use/participant-runs.js +8 -8
  237. package/dist/routes/computer-use/plan.d.ts +21 -29
  238. package/dist/routes/computer-use/plan.js +52 -60
  239. package/dist/routes/computer-use/preflight.d.ts +3 -5
  240. package/dist/routes/computer-use/preflight.js +20 -16
  241. package/dist/routes/computer-use/rerun-selection.js +10 -6
  242. package/dist/routes/computer-use/result.d.ts +1 -1
  243. package/dist/routes/computer-use/result.js +40 -30
  244. package/dist/routes/computer-use/route.d.ts +3 -4
  245. package/dist/routes/computer-use/route.js +21 -19
  246. package/dist/routes/computer-use/self-report.d.ts +2 -2
  247. package/dist/routes/computer-use/self-report.js +4 -4
  248. package/dist/routes/computer-use/setup.d.ts +8 -14
  249. package/dist/routes/computer-use/setup.js +96 -72
  250. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  251. package/dist/routes/computer-use/single-bundle.js +20 -25
  252. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  253. package/dist/routes/computer-use/subject-projection.js +20 -19
  254. package/dist/routes/computer-use/types.d.ts +169 -210
  255. package/dist/routes/computer-use/types.js +13 -5
  256. package/dist/routes/preview.js +0 -1
  257. package/dist/routes/scripted/bundle.d.ts +3 -6
  258. package/dist/routes/scripted/bundle.js +11 -16
  259. package/dist/routes/scripted/plan.d.ts +5 -7
  260. package/dist/routes/scripted/plan.js +6 -4
  261. package/dist/routes/scripted/result.d.ts +4 -1
  262. package/dist/routes/scripted/result.js +10 -6
  263. package/dist/routes/scripted/route.js +10 -11
  264. package/dist/routes/scripted/scenario.d.ts +1 -1
  265. package/dist/routes/scripted/scenario.js +1 -1
  266. package/dist/routes/scripted/setup.d.ts +3 -2
  267. package/dist/routes/scripted/setup.js +22 -21
  268. package/dist/routes/scripted/subject.d.ts +8 -3
  269. package/dist/routes/scripted/subject.js +9 -5
  270. package/dist/routes/scripted/surface-records.js +1 -1
  271. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  272. package/dist/routes/scripted/surface-sessions.js +4 -4
  273. package/dist/routes/scripted/types.d.ts +19 -36
  274. package/dist/routes/scripted/types.js +1 -2
  275. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  276. package/dist/routes/shared-world/bundle.d.ts +2 -2
  277. package/dist/routes/shared-world/bundle.js +22 -26
  278. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  279. package/dist/routes/shared-world/checkpoints.js +4 -4
  280. package/dist/routes/shared-world/comms.d.ts +5 -4
  281. package/dist/routes/shared-world/comms.js +28 -41
  282. package/dist/routes/shared-world/external-public.d.ts +5 -5
  283. package/dist/routes/shared-world/external-public.js +19 -20
  284. package/dist/routes/shared-world/handoff.d.ts +4 -4
  285. package/dist/routes/shared-world/handoff.js +50 -50
  286. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  287. package/dist/routes/shared-world/lobby-code.js +13 -13
  288. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  289. package/dist/routes/shared-world/{seats.js → participant-specs.js} +43 -48
  290. package/dist/routes/shared-world/plan.d.ts +2 -6
  291. package/dist/routes/shared-world/plan.js +1 -2
  292. package/dist/routes/shared-world/provenance.d.ts +4 -4
  293. package/dist/routes/shared-world/provenance.js +4 -4
  294. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  295. package/dist/routes/shared-world/provisioned.js +46 -40
  296. package/dist/routes/shared-world/result.js +31 -19
  297. package/dist/routes/shared-world/route.js +37 -41
  298. package/dist/routes/shared-world/setup.d.ts +5 -4
  299. package/dist/routes/shared-world/setup.js +12 -14
  300. package/dist/routes/shared-world/types.d.ts +53 -126
  301. package/dist/routes/shared-world/types.js +2 -2
  302. package/dist/routes/terminal/adapter.d.ts +8 -8
  303. package/dist/routes/terminal/adapter.js +28 -125
  304. package/dist/routes/terminal/bundle.d.ts +7 -12
  305. package/dist/routes/terminal/bundle.js +24 -34
  306. package/dist/routes/terminal/credentials.d.ts +2 -2
  307. package/dist/routes/terminal/credentials.js +16 -16
  308. package/dist/routes/terminal/dry-run.d.ts +1 -1
  309. package/dist/routes/terminal/dry-run.js +9 -11
  310. package/dist/routes/terminal/encoding.d.ts +1 -1
  311. package/dist/routes/terminal/encoding.js +2 -2
  312. package/dist/routes/terminal/ledger.d.ts +6 -6
  313. package/dist/routes/terminal/ledger.js +9 -9
  314. package/dist/routes/terminal/live-finish.d.ts +1 -2
  315. package/dist/routes/terminal/live-finish.js +21 -20
  316. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  317. package/dist/routes/terminal/live-sandbox.js +20 -20
  318. package/dist/routes/terminal/participant-text.d.ts +23 -0
  319. package/dist/routes/terminal/participant-text.js +165 -0
  320. package/dist/routes/terminal/plan.d.ts +2 -6
  321. package/dist/routes/terminal/plan.js +13 -9
  322. package/dist/routes/terminal/recorder.d.ts +6 -1
  323. package/dist/routes/terminal/recorder.js +12 -4
  324. package/dist/routes/terminal/result.js +4 -4
  325. package/dist/routes/terminal/route.js +26 -26
  326. package/dist/routes/terminal/runtime.d.ts +3 -2
  327. package/dist/routes/terminal/runtime.js +3 -3
  328. package/dist/routes/terminal/sandbox.d.ts +3 -3
  329. package/dist/routes/terminal/sandbox.js +9 -9
  330. package/dist/routes/terminal/session.js +16 -14
  331. package/dist/routes/terminal/token-usage.js +5 -5
  332. package/dist/routes/terminal/trace.d.ts +5 -8
  333. package/dist/routes/terminal/trace.js +9 -64
  334. package/dist/routes/terminal/types.d.ts +85 -93
  335. package/dist/routes/terminal/types.js +9 -4
  336. package/dist/run/active-runs.d.ts +13 -0
  337. package/dist/run/active-runs.js +12 -0
  338. package/dist/run/bundle-shape.d.ts +2 -1
  339. package/dist/run/bundle-shape.js +4 -4
  340. package/dist/run/bundle.d.ts +63 -56
  341. package/dist/run/bundle.js +9 -8
  342. package/dist/run/cost-summary.js +3 -2
  343. package/dist/run/costs.d.ts +6 -6
  344. package/dist/run/costs.js +10 -10
  345. package/dist/run/detail.d.ts +5 -5
  346. package/dist/run/detail.js +6 -6
  347. package/dist/run/dry-run.js +5 -12
  348. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  349. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  350. package/dist/run/feedback-shape.js +1 -1
  351. package/dist/run/judge.d.ts +16 -4
  352. package/dist/run/judge.js +24 -7
  353. package/dist/run/locate.d.ts +2 -0
  354. package/dist/run/locate.js +3 -1
  355. package/dist/run/outcomes.d.ts +3 -3
  356. package/dist/run/outcomes.js +3 -3
  357. package/dist/run/participant-records.d.ts +2 -2
  358. package/dist/run/participant-records.js +2 -2
  359. package/dist/run/paths.js +1 -1
  360. package/dist/run/pricing.d.ts +19 -9
  361. package/dist/run/pricing.js +30 -18
  362. package/dist/run/projection.d.ts +13 -13
  363. package/dist/run/projection.js +8 -8
  364. package/dist/run/reclaim.d.ts +6 -0
  365. package/dist/run/reclaim.js +13 -3
  366. package/dist/run/results.d.ts +1 -1
  367. package/dist/run/run-index.d.ts +1 -1
  368. package/dist/run/run-index.js +11 -11
  369. package/dist/run/run.d.ts +4 -2
  370. package/dist/run/run.js +9 -5
  371. package/dist/run/sandbox-receipts.d.ts +4 -4
  372. package/dist/run/sandbox-receipts.js +4 -4
  373. package/dist/run/shared-world-evidence.d.ts +47 -47
  374. package/dist/run/shared-world-shape.d.ts +3 -3
  375. package/dist/run/shared-world-shape.js +11 -11
  376. package/dist/run/stats.d.ts +5 -5
  377. package/dist/run/stats.js +8 -8
  378. package/dist/run/status.d.ts +16 -6
  379. package/dist/run/status.js +31 -8
  380. package/dist/run/streams.d.ts +26 -19
  381. package/dist/run/terminal-contract.d.ts +5 -5
  382. package/dist/run/terminal-contract.js +4 -4
  383. package/dist/run/transient-comms-secrets.d.ts +5 -0
  384. package/dist/run/transient-comms-secrets.js +12 -0
  385. package/dist/run-lab.d.ts +36 -34
  386. package/dist/run-lab.js +41 -37
  387. package/dist/subject/desktop-cli.d.ts +1 -1
  388. package/dist/subject/desktop-cli.js +1 -1
  389. package/dist/subject/local-tree-archive.d.ts +1 -1
  390. package/dist/subject/local-tree-archive.js +4 -4
  391. package/dist/subject/local-tree.d.ts +2 -2
  392. package/dist/subject/local-tree.js +1 -1
  393. package/dist/subject/node-bootstrap.d.ts +1 -1
  394. package/dist/subject/node-bootstrap.js +4 -4
  395. package/dist/subject/runtime.js +5 -5
  396. package/dist/subject/serve.js +1 -1
  397. package/dist/subject/steps.d.ts +4 -4
  398. package/dist/subject/steps.js +5 -5
  399. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  400. package/dist/substrates/e2b/cdp-probe.js +1 -1
  401. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  402. package/dist/substrates/e2b/desktop-browser.js +4 -4
  403. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  404. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  405. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  406. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  407. package/dist/substrates/e2b/desktop-media.js +2 -2
  408. package/dist/substrates/e2b/sandbox.js +1 -1
  409. package/dist/substrates/e2b/sdk.js +2 -2
  410. package/dist/substrates/local/runtime-host.d.ts +2 -0
  411. package/dist/substrates/local/runtime-host.js +6 -0
  412. package/dist/tui/actions.d.ts +7 -5
  413. package/dist/tui/actions.js +18 -9
  414. package/dist/tui-app.js +42 -42
  415. package/dist/verify/actor.d.ts +10 -10
  416. package/dist/verify/actor.js +15 -15
  417. package/dist/verify/artifacts.d.ts +1 -1
  418. package/dist/verify/artifacts.js +3 -3
  419. package/dist/verify/costs.d.ts +2 -2
  420. package/dist/verify/costs.js +2 -2
  421. package/dist/verify/liveness.d.ts +1 -1
  422. package/dist/verify/liveness.js +4 -1
  423. package/dist/verify/rerun.d.ts +1 -1
  424. package/dist/verify/rerun.js +1 -1
  425. package/dist/verify/shared-world.js +2 -2
  426. package/dist/verify/verify.js +6 -6
  427. package/docs/README.md +1 -1
  428. package/docs/architecture/actor-contract.md +60 -22
  429. package/docs/architecture/desktop-sessions.md +9 -9
  430. package/docs/architecture/external-public-shared-world.md +5 -0
  431. package/docs/architecture/observer.md +4 -4
  432. package/docs/architecture/restricted-codex-analysis.md +36 -2
  433. package/docs/architecture/state-driven-executor.md +4 -5
  434. package/docs/architecture/task-protocol-support.md +3 -5
  435. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  436. package/docs/contracts/run-bundle.md +10 -8
  437. package/docs/contracts/schemas.md +109 -53
  438. package/docs/contracts/study-analysis.md +24 -0
  439. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  440. package/docs/product/automatic-analysis.md +1 -0
  441. package/docs/ramp/README.md +2 -1
  442. package/package.json +4 -4
  443. package/skills/humanish/SKILL.md +3 -2
  444. package/skills/humanish/agents/openai.yaml +1 -1
  445. package/dist/deprecated.d.ts +0 -90
  446. package/dist/deprecated.js +0 -106
  447. package/dist/lab/bag-overrides.d.ts +0 -18
  448. package/dist/lab/bag-overrides.js +0 -121
  449. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  450. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  451. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  452. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  453. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -1,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
- }
@@ -1,15 +1,15 @@
1
- import { type AutomaticAnalysisHooks, type AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
1
+ import type { LabEvent } from "../../lab/run-lab-events.js";
2
+ import { type AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
2
3
  import type { ActorCompletionReason, ActorRuntimeProvenance, ActorStatus, ActorTrace } from "../../actors/contract.js";
3
- import { type RunLabProvenance } from "../../run/status.js";
4
4
  import type { CostCategory } from "../../run/terminal-contract.js";
5
5
  import type { RunScope } from "../../run/run.js";
6
6
  import type { buildRuntimeAuth } from "./credentials.js";
7
7
  import type { TerminalPlan } from "../../lab/plan-types.js";
8
+ import type { LabDeps } from "../../lab/lab-deps.js";
8
9
  import type { LabConfig } from "../../lab/types.js";
9
- import { type E2BDesktopModule } from "../../substrates/e2b/sdk.js";
10
- import { renderObserver, type ObserverResult } from "../../observer/render.js";
10
+ import type { ObserverResult } from "../../observer/render.js";
11
11
  import { type RunAdapterScore, type RunBundle, type RunFeedbackCandidate, type RunScorerProvenance } from "../../run/bundle.js";
12
- /** Provider-neutral metadata constant: the lane's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
12
+ /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
13
13
  export declare const TERMINAL_PRODUCT_LAB_PROVIDER_METADATA: {
14
14
  readonly mode: "terminal-product-lab";
15
15
  readonly tool: "humanish";
@@ -29,15 +29,19 @@ export declare const TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS: number;
29
29
  export declare const DEFAULT_REQUEST_TIMEOUT_MS = 60000;
30
30
  export declare const PRODUCT_SETUP_TIMEOUT_MS = 300000;
31
31
  export declare const TAIL_CHARS = 2000;
32
+ export declare const MESSAGE_CHARS = 8000;
33
+ export declare const TEXT_ITEMS_MAX = 200;
34
+ export declare const TEXT_ITEMS_BYTES: number;
35
+ export declare const PENDING_LINE_CHARS: number;
32
36
  export declare const MAX_TRANSCRIPT_BYTES: number;
33
37
  export declare const TERMINAL_PRODUCT_LAB_SCHEMA = "humanish.terminal-lab-result.v1";
34
38
  /**
35
39
  * The read-only evidence a thin adapter's scorer/feedback hook sees (the layer-6 extension seam,
36
40
  * issue #154 acceptance #8). It is the FULLY-ASSEMBLED, redacted, verifiable evidence — the live run
37
41
  * bundle, the provider-neutral actor trace, and the persisted ledgers (substrate/command/
38
- * interventions/cleanup/cost/no-spend). Every member is an EXPORTED public type, so a thin adapter
42
+ * interventions/cleanup/cost/no-spend). Every member is an exported public type, so a thin adapter
39
43
  * types against `import("humanish")` alone — never a deep `src/` import. The adapter reads this
40
- * to score the product attempt and derive feedback; it cannot mutate core's evidence (the lane
44
+ * to score the product attempt and derive feedback; it cannot mutate core's evidence (the route
41
45
  * attaches only the namespaced `RunAdapterScore` it returns + the feedback candidates it derives).
42
46
  */
43
47
  export interface TerminalProductScoringContext {
@@ -48,8 +52,8 @@ export interface TerminalProductScoringContext {
48
52
  /** The persisted terminal-product ledgers (lifecycle/command/interventions/cleanup/cost/no-spend). */
49
53
  ledgers: TerminalLedgers;
50
54
  /**
51
- * The FULL normalized transcript of the in-sandbox agent session — scrubbed (literal known
52
- * values) then redacted (shape patterns) AT THE SOURCE, capped at MAX_TRANSCRIPT_BYTES, and
55
+ * The full normalized transcript of the in-sandbox agent session, scrubbed (literal known
56
+ * values) then redacted (shape patterns) at the source, capped at MAX_TRANSCRIPT_BYTES, and
53
57
  * byte-identical to the persisted terminal-transcript.txt artifact. The trace's transcriptTail
54
58
  * is a ~2KB projection of this; a scorer needs the whole session so a rubric can find
55
59
  * command-tier evidence anywhere in it, not only in the tail window (#341).
@@ -63,44 +67,27 @@ export interface TerminalProductScoringContext {
63
67
  runId: string;
64
68
  }
65
69
  /**
66
- * Library-level hooks: the DI seams that drive the full live path against a fake sandbox + mock
67
- * CLI at zero spend. The deterministic merge-gate test wires loadModule (a fake @e2b/desktop
68
- * module) + env (the operator key source) + now (an injected clock); the live rung uses none of
69
- * them (it loads the real module and reads the real environment).
70
+ * Known spend lines for the terminal cost ledger. Core has no product, media or payment spend
71
+ * signal, so it fills only the provider line from trace tokenUsage when present. A test injects
72
+ * known lines through `LabDeps.costProbe`; absent signals keep the null-discipline default.
70
73
  */
71
- export interface TerminalProductLabHooks {
72
- /** Lazy-load the E2B module (tests inject a fake; default loadE2BDesktopModule). */
73
- loadModule?: () => Promise<E2BDesktopModule>;
74
+ export type TerminalCostProbe = (context: {
75
+ tokenCostUsd?: number;
76
+ }) => Partial<Record<"product" | "media" | "payment" | "provider", CostLine>> | undefined;
77
+ /** The scorer functions a terminal run calls: `RunLabOptions.scorer` without `deriveArtifacts`. */
78
+ export interface TerminalScorer {
74
79
  /**
75
- * The operator environment the lane reads the runtime key from (and from which it asserts no
76
- * banned credential is requested). Defaults to process.env. The runtime key is injected ONLY
77
- * into command-scoped `codex` env or an external header transform — NEVER Sandbox.create envs (the credential
78
- * boundary); tests plant a fake key here and assert it never reaches metadata/global env/artifacts.
79
- */
80
- env?: Record<string, string | undefined>;
81
- renderObserverFn?: typeof renderObserver;
82
- /** Injected clock for deterministic timestamps + wall-clock arithmetic (tests only). */
83
- now?: () => number;
84
- /**
85
- * Optional cost-ledger seam. Core has no product/media/payment spend signal, so it populates only
86
- * the provider line from trace tokenUsage when present. Tests and adapters can inject KNOWN spend
87
- * lines; absent signals retain the null-discipline default.
88
- */
89
- costProbe?: (context: {
90
- tokenCostUsd?: number;
91
- }) => Partial<Record<"product" | "media" | "payment" | "provider", CostLine>> | undefined;
92
- /**
93
- * THE LAYER-6 EXTENSION SEAM (issue #154 acceptance #8: "product-adapter hooks WITHOUT forking
94
- * core"). A thin in-repo/out-of-tree adapter registers a product scorer here. The lane calls it
80
+ * The layer-6 extension seam (issue #154 acceptance #8: "product-adapter hooks without forking
81
+ * core"). A thin in-repo/out-of-tree adapter registers a product scorer here. The route calls it
95
82
  * (when provided) over the fully-assembled evidence and attaches the returned, ADAPTER-NAMESPACED
96
- * `RunAdapterScore` to `bundle.adapterScore` WITHOUT core knowing any product noun (the score is
97
- * namespaced + its component breakdown rides in `data`). When NO scorer is given, the default
98
- * mission-based verdict (`review`) is unchanged. This is the SEAM the adopter's scorecard plugs
99
- * into — NOT a built-in product scorer (that lives in the adopter's repo).
83
+ * `RunAdapterScore` to `bundle.adapterScore` without core knowing any product noun (the score is
84
+ * namespaced + its component breakdown rides in `data`). When no scorer is given, the default
85
+ * mission-based verdict (`review`) is unchanged. The adopter's scorecard plugs in here; product
86
+ * scorers live in the adopter's repo, and core ships none.
100
87
  */
101
88
  score?: (ctx: TerminalProductScoringContext) => RunAdapterScore | Promise<RunAdapterScore>;
102
89
  /**
103
- * Companion seam: derive product-feedback candidates from the same assembled evidence. The lane
90
+ * Companion seam: derive product-feedback candidates from the same assembled evidence. The route
104
91
  * appends the returned candidates to `bundle.feedbackCandidates`. The adapter records its
105
92
  * product-specific concepts (public CLI command observed, hosted success-or-blocker, feedback id,
106
93
  * media/job ids, no-spend proof, defection/friction risk) under each candidate's ADAPTER-NAMESPACED
@@ -111,28 +98,38 @@ export interface TerminalProductLabHooks {
111
98
  deriveFeedback?: (ctx: TerminalProductScoringContext) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
112
99
  }
113
100
  export interface RunTerminalProductLabOptions {
114
- automaticAnalysis?: AutomaticAnalysisHooks;
115
- /** Which manifest produced this run (#455); threaded into the status record + bundle. */
116
- lab?: RunLabProvenance;
101
+ /** Cancels post-run analysis only. */
102
+ analysisSignal?: AbortSignal;
103
+ /** Reports the analysis window to onEvent; built by normalizeRunLabOptions. */
104
+ emit?: (event: LabEvent) => void;
117
105
  cwd: string;
118
106
  config: LabConfig;
119
107
  /** Resolved upstream (scenario.mode + CLI override); defaults safe (dry-run). */
120
108
  dryRun: boolean;
121
109
  open?: boolean;
122
110
  runId?: string;
123
- hooks?: TerminalProductLabHooks;
124
111
  /**
125
- * Present ONLY when the scorer hooks were CONFIG-DECLARED and loaded by the CLI (#316). Its presence
126
- * is the "declared" marker: a config-declared terminal scorer returning status:"fail" FLIPS
112
+ * The operator environment the route reads the runtime key from (and from which it asserts no
113
+ * banned credential is requested). Defaults to process.env. The runtime key goes only
114
+ * into command-scoped `codex` env or an external header transform, and never into Sandbox.create envs (the credential
115
+ * boundary); tests plant a fake key here and assert it never reaches metadata/global env/artifacts.
116
+ */
117
+ env?: Readonly<Record<string, string | undefined>>;
118
+ scorer?: TerminalScorer;
119
+ /** Test seams: the E2B module, the Observer renderer, the clock and the cost probe. */
120
+ deps?: LabDeps;
121
+ /**
122
+ * Present only when the scorer was config-declared and loaded by the CLI (#316). Its presence
123
+ * is the "declared" marker: a config-declared terminal scorer returning status:"fail" flips
127
124
  * bundle.review.verdict (like the browser routes), and one that throws becomes a visible review.gaps
128
- * entry. A LIBRARY caller passing `hooks` directly leaves this ABSENT and keeps today's purely
125
+ * entry. A library caller passing `scorer` leaves this absent and keeps today's purely
129
126
  * additive terminal behavior (verdict unchanged). Core-computed, never adopter-supplied.
130
127
  */
131
128
  scorerProvenance?: RunScorerProvenance;
132
129
  }
133
130
  export interface TerminalProductLabResult extends AutomaticAnalysisResult {
134
131
  schema: typeof TERMINAL_PRODUCT_LAB_SCHEMA;
135
- /** True when the bundle verified AND (dry-run, or the live session reached a terminal verdict
132
+ /** True when the bundle verified and (dry-run, or the live session reached a terminal verdict
136
133
  * without a harness error + cleanup was proven). The agent's pass/fail is evidence, not the
137
134
  * lab's exit code. */
138
135
  ok: boolean;
@@ -150,7 +147,7 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult {
150
147
  completionReason: ActorCompletionReason;
151
148
  reason: string;
152
149
  };
153
- /** Live-only: the sandbox lifecycle proof (the key/auth value is NEVER surfaced here). */
150
+ /** Live-only: the sandbox lifecycle proof (the key/auth value is never surfaced here). */
154
151
  sandbox?: {
155
152
  sandboxId: string;
156
153
  killed: boolean;
@@ -163,10 +160,10 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult {
163
160
  cost?: {
164
161
  knownTotalUsd: number;
165
162
  fullyMeasured: boolean;
166
- /** Per-category USD: a known number, or null = NOT MEASURED (never coerced to 0). */
163
+ /** Per-category USD: a known number, or null = not measured (never coerced to 0). */
167
164
  lines: Record<"product" | "media" | "payment" | "provider", number | null>;
168
165
  };
169
- /** Live-only: the no-spend proof DERIVED from the ledger. */
166
+ /** Live-only: the no-spend proof derived from the ledger. */
170
167
  noSpend?: {
171
168
  satisfied: boolean;
172
169
  maxUsd: number | null;
@@ -176,12 +173,7 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult {
176
173
  observer?: ObserverResult;
177
174
  warnings: string[];
178
175
  error?: {
179
- /**
180
- * HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED is deprecated and no longer produced: the terminal
181
- * agent runs only inside this route, and its fail-closed direct runner is gone. That code
182
- * goes in the next minor.
183
- */
184
- code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_CONFLICT" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_FAILED" | "HUMANISH_TERMINAL_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_SUBJECT_INVALID" | "HUMANISH_TERMINAL_LAB_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_LAB_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_LAB_KEYS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_INVALID" | "HUMANISH_TERMINAL_LAB_UNPRICED_CAP" | "HUMANISH_TERMINAL_LAB_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_LAB_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_LAB_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE" | "HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED";
176
+ code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_FAILED" | "HUMANISH_TERMINAL_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_SUBJECT_INVALID" | "HUMANISH_TERMINAL_LAB_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_LAB_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_LAB_KEYS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_INVALID" | "HUMANISH_TERMINAL_LAB_UNPRICED_CAP" | "HUMANISH_TERMINAL_LAB_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_LAB_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_LAB_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE";
185
177
  message: string;
186
178
  };
187
179
  }
@@ -192,14 +184,14 @@ export interface LifecycleRecord {
192
184
  /** Redacted+scrubbed before persisting (it never carries a secret, but the harness never trusts that). */
193
185
  message: string;
194
186
  }
195
- /** Command-log ledger entry: which command ran, with what exit/duration (NEVER its env values). */
187
+ /** Command-log ledger entry: which command ran, with what exit/duration (never its env values). */
196
188
  export interface CommandLogRecord {
197
189
  at: string;
198
190
  /** A public-safe label for the command (e.g. "codex-exec"); the full argv is bound by digest only. */
199
191
  label: string;
200
192
  /** sha256-12 of the exact command string — pins "same recipe" without persisting it. */
201
193
  commandDigest: string;
202
- /** The env var NAMES injected command-scoped (values NEVER persisted) — the credential evidence. */
194
+ /** The env var names injected command-scoped (values never persisted): the credential evidence. */
203
195
  envNames: string[];
204
196
  exitCode?: number;
205
197
  timedOut?: boolean;
@@ -209,12 +201,12 @@ export interface CommandLogRecord {
209
201
  export interface TerminalEventRecord {
210
202
  at: string;
211
203
  stream: "stdout" | "stderr";
212
- /** ALREADY scrubbed (literal known values) THEN redacted (shape patterns) at the source. */
204
+ /** Already scrubbed (literal known values), then redacted (shape patterns) at the source. */
213
205
  chunk: string;
214
206
  }
215
207
  /**
216
- * One operator intervention (assisted-input event). The current route ships NO assisted-input
217
- * path, so this ledger is ALWAYS empty — but always PRESENT (the safety contract: empty-present is
208
+ * One operator intervention (assisted-input event). The current route ships no assisted-input
209
+ * path, so this ledger is always empty, and always present (the safety contract: empty-present is
218
210
  * the contract, an absent ledger fails verify). A future assisted path can fill this shape.
219
211
  */
220
212
  export interface InterventionRecord {
@@ -224,28 +216,28 @@ export interface InterventionRecord {
224
216
  inputDigest: string;
225
217
  }
226
218
  /**
227
- * One cost line of the spend ledger. THE NULL DISCIPLINE (issue #154, the cost/no-spend asks):
228
- * three distinct states are crisply modeled and NEVER conflated —
229
- * - `usd: 0` => KNOWN to be zero. A measured-and-zero spend (we metered this category and it
219
+ * One cost line of the spend ledger. The null discipline (issue #154, the cost/no-spend asks):
220
+ * three distinct states are kept apart:
221
+ * - `usd: 0` => known to be zero. A measured-and-zero spend (we metered this category and it
230
222
  * billed nothing). The no-spend proof may legitimately assert this is zero.
231
- * - `usd: null` => NOT MEASURED. This run carries no spend signal for the category. `null` is
223
+ * - `usd: null` => not measured. This run carries no spend signal for the category. `null` is
232
224
  * written explicitly (never undefined-omitted, never guessed to 0). The no-spend
233
- * proof must list this line as UNMEASURED and must NOT claim it is zero.
234
- * - line ABSENT => NOT APPLICABLE to this lane/run (n/a). The line simply does not appear in
225
+ * proof must list this line as unmeasured and must not claim it is zero.
226
+ * - line absent => not applicable to this route/run (n/a). The line simply does not appear in
235
227
  * `lines`. (The current route emits all four lines, so absence is reserved for
236
- * future lanes that genuinely have no such category.)
228
+ * future routes that genuinely have no such category.)
237
229
  * `null` vs missing-key is the load-bearing distinction: a missing key means "this category does not
238
230
  * exist for this run"; a present key with `null` means "this category exists but we did not measure
239
231
  * it". A no-spend proof that claimed zero on a `null` line would claim more than it measured.
240
232
  */
241
233
  export interface CostLine {
242
- /** known zero (0) | not measured (null). The key is ALWAYS present when the line is applicable. */
234
+ /** known zero (0) | not measured (null). The key is always present when the line is applicable. */
243
235
  usd: number | null;
244
236
  /** Optional billable-unit count, same discipline: a known count, or null = not measured. */
245
237
  count?: number | null;
246
238
  /** How this line's value was established (provenance for the verifier + the human reviewer). */
247
239
  source: "provider-token-usage" | "no-spend-signal" | "operator-cap" | "unmeasured"
248
- /** Tokens were COUNTED but no rate could price them, so `usd` stays null while the note
240
+ /** Tokens were counted but no rate could price them, so `usd` stays null while the note
249
241
  * carries the measured token totals (#531). Distinct from "unmeasured", which means no
250
242
  * signal at all. */
251
243
  | "unpriced-token-usage";
@@ -253,39 +245,39 @@ export interface CostLine {
253
245
  note: string;
254
246
  }
255
247
  /**
256
- * The spend ledger (a block of `TerminalLedgers`). The no-spend PROOF is DERIVED from this — never
257
- * asserted independently. Every applicable category appears as a line; unknowns are `null`.
248
+ * The spend ledger (a block of `TerminalLedgers`). The no-spend proof is derived from this and
249
+ * never asserted independently. Every applicable category appears as a line; unknowns are `null`.
258
250
  */
259
251
  export interface TerminalCostLedger {
260
252
  schema: "humanish.terminal-cost-ledger.v1";
261
- /** USD currency unit (recorded explicitly so a future multi-currency lane is unambiguous). */
253
+ /** USD currency unit (recorded explicitly so a future multi-currency route is unambiguous). */
262
254
  currency: "usd";
263
255
  lines: Record<CostCategory, CostLine>;
264
- /** Sum of the KNOWN (non-null) lines. null lines contribute NOTHING and are NOT guessed as 0. */
256
+ /** Sum of the known (non-null) lines. Null lines contribute nothing and are never guessed as 0. */
265
257
  knownTotalUsd: number;
266
- /** True when every applicable line is measured (no null). When false, knownTotalUsd is a LOWER
267
- * bound, not the full spend — the no-spend proof says so honestly. */
258
+ /** True when every applicable line is measured (no null). When false, knownTotalUsd is a lower
259
+ * bound on the spend, and the no-spend proof says so. */
268
260
  fullyMeasured: boolean;
269
261
  }
270
262
  /**
271
- * The no-spend proof, DERIVED from the cost ledger (issue #154: "derived from a ledger, not
272
- * asserted"). It is honest about what it knows: it lists the KNOWN-zero lines it can vouch for and,
273
- * separately, the UNMEASURED (null) lines it CANNOT vouch for. `satisfied` is true only when every
274
- * KNOWN line is zero (a known non-zero line fails it); but a proof with unmeasured lines explicitly
275
- * says it could not measure them — it never claims zero on a line the ledger marks null.
263
+ * The no-spend proof, derived from the cost ledger (issue #154: "derived from a ledger, not
264
+ * asserted"). It lists the known-zero lines it can vouch for and, separately, the unmeasured
265
+ * (null) lines it cannot vouch for. `satisfied` is true only when every known line is zero (a
266
+ * known non-zero line fails it). A proof with unmeasured lines says it could not measure them;
267
+ * it never claims zero on a line the ledger marks null.
276
268
  */
277
269
  export interface NoSpendProof {
278
270
  schema: "humanish.terminal-no-spend-proof.v1";
279
271
  /** The maxUsd cap this proof was evaluated against (the no-spend scenario declares maxUsd: 0). */
280
272
  maxUsd: number | null;
281
- /** True iff every KNOWN (measured) line is <= maxUsd (for a no-spend run, == 0). */
273
+ /** True iff every known (measured) line is <= maxUsd (for a no-spend run, == 0). */
282
274
  satisfied: boolean;
283
- /** Categories the ledger MEASURED and found at (known) zero — the proof CAN vouch for these. */
275
+ /** Categories the ledger measured and found at (known) zero: the proof can vouch for these. */
284
276
  knownZeroLines: CostCategory[];
285
277
  /** Categories the ledger measured with a known NON-zero spend (these break `satisfied`). */
286
278
  knownNonZeroLines: CostCategory[];
287
- /** Categories the ledger marks `null` (NOT MEASURED). The proof explicitly lists these and does
288
- * NOT claim they are zero — it claims only that this run could not measure them. */
279
+ /** Categories the ledger marks `null` (not measured). The proof lists these and does not claim
280
+ * they are zero; it claims only that this run could not measure them. */
289
281
  unmeasuredLines: CostCategory[];
290
282
  /** Sum of the known lines (== 0 for a satisfied no-spend run). */
291
283
  knownTotalUsd: number;
@@ -298,25 +290,25 @@ export interface TerminalLedgers {
298
290
  runtime?: ActorRuntimeProvenance;
299
291
  lifecycle: LifecycleRecord[];
300
292
  commandLog: CommandLogRecord[];
301
- /** ALWAYS present; ALWAYS empty while no assisted-input path ships — the safety contract. */
293
+ /** Always present, and always empty while no assisted-input path ships (the safety contract). */
302
294
  interventions: InterventionRecord[];
303
295
  cleanup: {
304
296
  /** True when exact-id kill resolved, including the startup guard's acquired-instance kill
305
297
  * (found-and-killed or already gone both prove absence; see `remaining`/`reason`). */
306
298
  killed: boolean;
307
- /** BY-ID proof, NEVER derived from Sandbox.list: 0 = confirmed reclaimed (kill(id) RESOLVED
308
- * -- returned true "found and killed" OR false "404, exact id already gone" -- and, when the
299
+ /** By-id proof, never derived from Sandbox.list: 0 = confirmed reclaimed (kill(id) resolved,
300
+ * returning true "found and killed" or false "404, exact id already gone", and, when the
309
301
  * SDK exposes it, getInfo(id) did not report a live sandbox); 1 = getInfo(id) still reports
310
- * this exact sandbox running/paused (NOT reclaimed); -1 = kill(id) itself failed, threw, or
302
+ * this exact sandbox running/paused (still present); -1 = kill(id) itself failed, threw, or
311
303
  * was unavailable (the server-side kill-on-timeout is the backstop). */
312
304
  remaining: number;
313
305
  /** Honest, human-readable statement of which by-id signal produced `remaining`. */
314
306
  reason: string;
315
307
  };
316
308
  /** The spend ledger. Unknowns are `null`, never guessed; the no-spend proof
317
- * below is DERIVED from it. */
309
+ * below is derived from it. */
318
310
  cost: TerminalCostLedger;
319
- /** The no-spend proof DERIVED from `cost`. Never an independent assertion. */
311
+ /** The no-spend proof derived from `cost`. Never an independent assertion. */
320
312
  noSpendProof: NoSpendProof;
321
313
  }
322
314
  /** What a terminal run takes besides its plan. The plan carries the config, dry run and lab. */