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
@@ -3,7 +3,7 @@
3
3
  import path from "node:path";
4
4
  import { runIdOf } from "../run/paths.js";
5
5
  import { assertPreparedSelectedOutputDirectory, prepareContainedOutputDirectoryRoot, writeContainedOutputFile, } from "../run/contained-output.js";
6
- import { pathMissing, readBoundedStudyFile } from "../run/study-files.js";
6
+ import { pathMissing, readBoundedFile } from "../run/evidence-files.js";
7
7
  import { ANALYSIS_MAX_BYTES, MAX_VERSIONS, ANALYSIS_DIRECTORY, ANALYSIS_EXECUTION_DIRECTORY, claimDirectory, directoryIds, existingRoot, safeId, } from "./store.js";
8
8
  import { hashAnalysisValue, analysisExecutionStartSchema, validateAnalysisArtifact, validateAnalysisExecutionReceipt, } from "./validation.js";
9
9
  /** receipt.json and start.json in an execution directory. */
@@ -17,14 +17,14 @@ const EXECUTION_BINDING_KEYS = [
17
17
  "promptVersion",
18
18
  ];
19
19
  /** Exact bounded receipt lookup for an already claimed execution, never a dispatch decision. */
20
- export async function readStudyAnalysisExecution(prepared, id) {
20
+ export async function readAnalysisExecution(prepared, id) {
21
21
  if (!safeId(id))
22
22
  return null;
23
23
  try {
24
24
  const root = await existingRoot(prepared, ANALYSIS_EXECUTION_DIRECTORY);
25
25
  if (!root)
26
26
  return null;
27
- const bytes = await readBoundedStudyFile(root, `${id}/receipt.json`, MAX_EXECUTION_RECORD_BYTES);
27
+ const bytes = await readBoundedFile(root, `${id}/receipt.json`, MAX_EXECUTION_RECORD_BYTES);
28
28
  if (!bytes)
29
29
  return null;
30
30
  const receipt = validateAnalysisExecutionReceipt(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)));
@@ -38,7 +38,7 @@ export async function readStudyAnalysisExecution(prepared, id) {
38
38
  * Publish accounting first. Unlike a usable report, this receipt does not claim
39
39
  * the source still matches; its digests name the exact input that was attempted.
40
40
  */
41
- export async function writeStudyAnalysisExecutionReceipt(prepared, value) {
41
+ export async function writeAnalysisExecutionReceipt(prepared, value) {
42
42
  const receipt = executionReceipt(value, prepared);
43
43
  const root = await prepareContainedOutputDirectoryRoot(prepared, ANALYSIS_EXECUTION_DIRECTORY);
44
44
  const claimed = await claimDirectory(root, receipt.id);
@@ -68,7 +68,7 @@ function executionReceipt(value, prepared) {
68
68
  return receipt;
69
69
  }
70
70
  /** The returned closure owns one exact directory; persisted IDs never authorize overwriting it. */
71
- export async function beginStudyAnalysisExecution(prepared, context) {
71
+ export async function beginAnalysisExecution(prepared, context) {
72
72
  const start = analysisExecutionStartSchema.parse({
73
73
  ...context,
74
74
  schema: "humanish.analysis-execution-start.v1",
@@ -92,7 +92,7 @@ export async function beginStudyAnalysisExecution(prepared, context) {
92
92
  await writeContainedOutputFile(claimed, "receipt.json", `${JSON.stringify(receipt, null, 2)}\n`);
93
93
  };
94
94
  }
95
- export async function listStudyAnalysisExecutions(prepared) {
95
+ export async function listAnalysisExecutions(prepared) {
96
96
  const receipts = [];
97
97
  const warnings = [];
98
98
  try {
@@ -102,7 +102,7 @@ export async function listStudyAnalysisExecutions(prepared) {
102
102
  const inventory = await directoryIds(root, MAX_VERSIONS);
103
103
  warnings.push(...inventory.warnings);
104
104
  for (const id of inventory.ids) {
105
- const bytes = await readBoundedStudyFile(root, `${id}/receipt.json`, MAX_EXECUTION_RECORD_BYTES);
105
+ const bytes = await readBoundedFile(root, `${id}/receipt.json`, MAX_EXECUTION_RECORD_BYTES);
106
106
  if (!bytes) {
107
107
  if (!(await pathMissing(path.join(root.physicalPath, id, "receipt.json")).catch(() => false)))
108
108
  warnings.push("ANALYSIS_RECEIPT_UNREADABLE");
@@ -128,7 +128,7 @@ export async function listStudyAnalysisExecutions(prepared) {
128
128
  return { receipts, warnings: [...new Set(warnings)] };
129
129
  }
130
130
  /** Accounting is independent of source freshness and findings validation. No evidence is opened. */
131
- export async function readStudyAnalysisAccountingRecords(prepared) {
131
+ export async function readAnalysisAccountingRecords(prepared) {
132
132
  const records = new Map();
133
133
  const warnings = [];
134
134
  for (const directory of [ANALYSIS_EXECUTION_DIRECTORY, ANALYSIS_DIRECTORY]) {
@@ -145,7 +145,7 @@ export async function readStudyAnalysisAccountingRecords(prepared) {
145
145
  records.set(id, record);
146
146
  }
147
147
  if (directory === ANALYSIS_EXECUTION_DIRECTORY) {
148
- const startBytes = await readBoundedStudyFile(root, `${id}/start.json`, MAX_EXECUTION_RECORD_BYTES);
148
+ const startBytes = await readBoundedFile(root, `${id}/start.json`, MAX_EXECUTION_RECORD_BYTES);
149
149
  if (startBytes) {
150
150
  try {
151
151
  const start = analysisExecutionStartSchema.parse(JSON.parse(startBytes.toString("utf8")));
@@ -159,7 +159,7 @@ export async function readStudyAnalysisAccountingRecords(prepared) {
159
159
  }
160
160
  }
161
161
  const legacy = directory === ANALYSIS_DIRECTORY;
162
- const bytes = await readBoundedStudyFile(root, `${id}/${legacy ? "analysis.json" : "receipt.json"}`, legacy ? ANALYSIS_MAX_BYTES : MAX_EXECUTION_RECORD_BYTES);
162
+ const bytes = await readBoundedFile(root, `${id}/${legacy ? "analysis.json" : "receipt.json"}`, legacy ? ANALYSIS_MAX_BYTES : MAX_EXECUTION_RECORD_BYTES);
163
163
  if (!bytes)
164
164
  continue;
165
165
  try {
@@ -169,7 +169,7 @@ export async function readStudyAnalysisAccountingRecords(prepared) {
169
169
  // A historical report may have stale captures or invalid findings. Its strictly checked
170
170
  // accounting metadata still records incurred usage; it never approves those findings.
171
171
  const candidate = legacy
172
- ? Object.fromEntries(Object.keys(studyAnalysisExecutionReceiptKeys).map((key) => [key, raw[key]]))
172
+ ? Object.fromEntries(Object.keys(analysisExecutionReceiptKeys).map((key) => [key, raw[key]]))
173
173
  : raw;
174
174
  if (legacy)
175
175
  Object.assign(candidate, {
@@ -208,7 +208,7 @@ export async function readStudyAnalysisAccountingRecords(prepared) {
208
208
  }
209
209
  return { records: [...records.values()], warnings: [...new Set(warnings)] };
210
210
  }
211
- const studyAnalysisExecutionReceiptKeys = {
211
+ const analysisExecutionReceiptKeys = {
212
212
  id: true,
213
213
  runId: true,
214
214
  status: true,
@@ -18,14 +18,14 @@ export declare function assertAnalysisPublicationCapacity(prepared: PreparedRunA
18
18
  export declare function existingRoot(prepared: PreparedRunArtifactPaths, directory?: string): Promise<PreparedSelectedOutputDirectory | null>;
19
19
  export declare function claimDirectory(parent: PreparedSelectedOutputDirectory, id: string): Promise<PreparedSelectedOutputDirectory>;
20
20
  /** A claimed version is never reused, including after interruption before publication. */
21
- export declare function writeStudyAnalysis(prepared: PreparedRunArtifactPaths, value: AnalysisArtifact): Promise<void>;
21
+ export declare function writeAnalysis(prepared: PreparedRunArtifactPaths, value: AnalysisArtifact): Promise<void>;
22
22
  export declare function directoryIds(root: PreparedSelectedOutputDirectory, limit: number, ignoreLegacyFiles?: boolean): Promise<{
23
23
  ids: string[];
24
24
  warnings: string[];
25
25
  }>;
26
26
  /** Read one exact result without reading automatic job state or unrelated history. */
27
- export declare function readStudyAnalysisVersion(prepared: PreparedRunArtifactPaths, id: string): Promise<AnalysisListEntry | null>;
27
+ export declare function readAnalysisVersion(prepared: PreparedRunArtifactPaths, id: string): Promise<AnalysisListEntry | null>;
28
28
  /** Includes failed attempts; callers must not equate the newest attempt with usable findings. */
29
29
  export declare function listAnalyses(prepared: PreparedRunArtifactPaths): Promise<AnalysisListEntry[]>;
30
- export declare function loadStudyAnalysisRecord(prepared: PreparedRunArtifactPaths, id?: string): Promise<LoadedAnalysis>;
31
- export declare function appendStudyAnalysisCorrection(prepared: PreparedRunArtifactPaths, value: AnalysisCorrection): Promise<void>;
30
+ export declare function loadAnalysisRecord(prepared: PreparedRunArtifactPaths, id?: string): Promise<LoadedAnalysis>;
31
+ export declare function appendAnalysisCorrection(prepared: PreparedRunArtifactPaths, value: AnalysisCorrection): Promise<void>;
@@ -4,7 +4,7 @@ import path from "node:path";
4
4
  import { physicalCwdOf, runIdOf, validatePreparedRunRootIdentity, } from "../run/paths.js";
5
5
  import { assertPreparedSelectedOutputDirectory, bindExistingManagedHumanishOutputDirectory, prepareContainedOutputDirectoryRoot, writeContainedOutputFile, } from "../run/contained-output.js";
6
6
  import { EVIDENCE_LIMITS, validateAnalysisEvidence } from "./evidence.js";
7
- import { pathMissing, isStudyEvidencePath, readBoundedStudyFile } from "../run/study-files.js";
7
+ import { pathMissing, isEvidencePath, readBoundedFile } from "../run/evidence-files.js";
8
8
  import { hashAnalysisValue, validateAnalysisArtifact, validateAnalysisCorrection, } from "./validation.js";
9
9
  import { ANALYSIS_ID_PATTERN, } from "./types.js";
10
10
  import { RUN_BUNDLE_FILE } from "../run/bundle.js";
@@ -61,9 +61,9 @@ export async function claimDirectory(parent, id) {
61
61
  return prepareContainedOutputDirectoryRoot(parent, id);
62
62
  }
63
63
  /** A claimed version is never reused, including after interruption before publication. */
64
- export async function writeStudyAnalysis(prepared, value) {
64
+ export async function writeAnalysis(prepared, value) {
65
65
  const artifact = validateAnalysisArtifact(value);
66
- const source = await readBoundedStudyFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
66
+ const source = await readBoundedFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
67
67
  if (!source)
68
68
  throw new Error("ANALYSIS_SOURCE_UNAVAILABLE");
69
69
  await validateAnalysisEvidence(prepared, artifact, source);
@@ -73,7 +73,7 @@ export async function writeStudyAnalysis(prepared, value) {
73
73
  const root = await prepareContainedOutputDirectoryRoot(prepared, ANALYSIS_DIRECTORY);
74
74
  const claimed = await claimDirectory(root, artifact.id);
75
75
  // Recheck source immediately before publishing the immutable record.
76
- const current = await readBoundedStudyFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
76
+ const current = await readBoundedFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
77
77
  if (!current?.equals(source))
78
78
  throw new Error("ANALYSIS_SOURCE_CHANGED");
79
79
  await writeContainedOutputFile(claimed, "analysis.json", bytes);
@@ -100,7 +100,7 @@ export async function directoryIds(root, limit, ignoreLegacyFiles = false) {
100
100
  if (entry.name.startsWith(".humanish-write-"))
101
101
  continue;
102
102
  if (ignoreLegacyFiles &&
103
- isStudyEvidencePath(entry.name) &&
103
+ isEvidencePath(entry.name) &&
104
104
  !["analysis.json", "correction.json", "receipt.json"].includes(entry.name))
105
105
  continue;
106
106
  warnings.push("ANALYSIS_UNSAFE_ENTRY_IGNORED");
@@ -118,7 +118,7 @@ export async function directoryIds(root, limit, ignoreLegacyFiles = false) {
118
118
  async function readVersion(prepared, root, id, source) {
119
119
  if (!safeId(id))
120
120
  return { id: "invalid", state: "invalid", analysis: null, warnings: ["ANALYSIS_ID_INVALID"] };
121
- const bytes = await readBoundedStudyFile(root, `${id}/analysis.json`, ANALYSIS_MAX_BYTES);
121
+ const bytes = await readBoundedFile(root, `${id}/analysis.json`, ANALYSIS_MAX_BYTES);
122
122
  // A claimed directory without a published record is an interrupted write, not a report.
123
123
  if (bytes === null) {
124
124
  if (await pathMissing(path.join(root.physicalPath, id, "analysis.json")).catch(() => false))
@@ -159,14 +159,14 @@ async function readVersion(prepared, root, id, source) {
159
159
  return { id, state: "ready", analysis, warnings: [] };
160
160
  }
161
161
  /** Read one exact result without reading automatic job state or unrelated history. */
162
- export async function readStudyAnalysisVersion(prepared, id) {
162
+ export async function readAnalysisVersion(prepared, id) {
163
163
  if (!safeId(id))
164
164
  return null;
165
165
  try {
166
166
  const root = await existingRoot(prepared);
167
167
  if (!root)
168
168
  return null;
169
- return await readVersion(prepared, root, id, await readBoundedStudyFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes));
169
+ return await readVersion(prepared, root, id, await readBoundedFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes));
170
170
  }
171
171
  catch {
172
172
  return null;
@@ -179,7 +179,7 @@ export async function listAnalyses(prepared) {
179
179
  if (!root)
180
180
  return [];
181
181
  const inventory = await directoryIds(root, MAX_VERSIONS, true);
182
- const source = await readBoundedStudyFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
182
+ const source = await readBoundedFile(prepared, RUN_BUNDLE_FILE, EVIDENCE_LIMITS.sourceBytes);
183
183
  const results = [];
184
184
  for (const id of inventory.ids) {
185
185
  const entry = await readVersion(prepared, root, id, source);
@@ -219,7 +219,7 @@ async function readCorrections(prepared, root, analysis) {
219
219
  const inventory = await directoryIds(bound, MAX_CORRECTIONS);
220
220
  warnings.push(...inventory.warnings);
221
221
  for (const id of inventory.ids) {
222
- const bytes = await readBoundedStudyFile(root, `${analysis.id}/corrections/${id}/correction.json`, MAX_CORRECTION_BYTES);
222
+ const bytes = await readBoundedFile(root, `${analysis.id}/corrections/${id}/correction.json`, MAX_CORRECTION_BYTES);
223
223
  if (!bytes) {
224
224
  // An unpublished claim directory is harmless; a present record that
225
225
  // cannot be checked must not silently erase a prior review decision.
@@ -246,7 +246,7 @@ async function readCorrections(prepared, root, analysis) {
246
246
  corrections.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id));
247
247
  return { corrections, warnings };
248
248
  }
249
- export async function loadStudyAnalysisRecord(prepared, id) {
249
+ export async function loadAnalysisRecord(prepared, id) {
250
250
  if (id !== undefined && !safeId(id))
251
251
  return empty("invalid", ["ANALYSIS_ID_INVALID"]);
252
252
  try {
@@ -290,9 +290,9 @@ function assertCorrectionBinding(analysis, correction) {
290
290
  Date.parse(correction.createdAt) < Date.parse(analysis.completedAt))
291
291
  throw new Error("ANALYSIS_CORRECTION_BINDING_INVALID");
292
292
  }
293
- export async function appendStudyAnalysisCorrection(prepared, value) {
293
+ export async function appendAnalysisCorrection(prepared, value) {
294
294
  const correction = validateAnalysisCorrection(value);
295
- const loaded = await loadStudyAnalysisRecord(prepared, correction.analysisId);
295
+ const loaded = await loadAnalysisRecord(prepared, correction.analysisId);
296
296
  if (loaded.state !== "ready" || !loaded.analysis)
297
297
  throw new Error("ANALYSIS_CORRECTION_SOURCE_UNAVAILABLE");
298
298
  assertCorrectionBinding(loaded.analysis, correction);
@@ -2,6 +2,7 @@ import type { RunLabOptions } from "../../run-lab.js";
2
2
  import type { CliIo } from "../io.js";
3
3
  /**
4
4
  * Post-run analysis cancellation for the CLI: while analysis runs, SIGINT, SIGTERM and SIGHUP abort
5
- * it. The listeners exist only during analysis, so actor signal behavior is unchanged.
5
+ * it. The listeners exist only during analysis; before it, the run's own handlers
6
+ * (run-signals.ts) hold the signals and hand them over here.
6
7
  */
7
8
  export declare function cliAnalysisOptions(io: Pick<CliIo, "writeErr">): Pick<RunLabOptions, "onEvent" | "analysisSignal">;
@@ -1,6 +1,8 @@
1
+ import { handOverRunSignals } from "./run-signals.js";
1
2
  /**
2
3
  * Post-run analysis cancellation for the CLI: while analysis runs, SIGINT, SIGTERM and SIGHUP abort
3
- * it. The listeners exist only during analysis, so actor signal behavior is unchanged.
4
+ * it. The listeners exist only during analysis; before it, the run's own handlers
5
+ * (run-signals.ts) hold the signals and hand them over here.
4
6
  */
5
7
  export function cliAnalysisOptions(io) {
6
8
  const controller = new AbortController();
@@ -13,6 +15,7 @@ export function cliAnalysisOptions(io) {
13
15
  onEvent: (event) => {
14
16
  if (event.type === "analysis-started") {
15
17
  io.writeErr("Participants finished; preparing analysis…\n");
18
+ handOverRunSignals();
16
19
  for (const signal of signals)
17
20
  process.on(signal, cancel);
18
21
  }
@@ -3,7 +3,7 @@ import { Command, Option } from "commander";
3
3
  import { forTerminal } from "../../routes/terminal/encoding.js";
4
4
  import { analyzeRun, correctAnalysis, dryRunBundleRefusal, showAnalysis, } from "../../analysis/service.js";
5
5
  import { listAnalyses } from "../../analysis/store.js";
6
- import { listStudyAnalysisExecutions } from "../../analysis/store-executions.js";
6
+ import { listAnalysisExecutions } from "../../analysis/store-executions.js";
7
7
  import { resolveRunPath } from "../../run/locate.js";
8
8
  import { discoverCliKeys, JSON_OPTION_DESCRIPTION, writeResult } from "../io.js";
9
9
  import { resolvePhysicalCwd } from "../../run/paths.js";
@@ -132,6 +132,8 @@ async function handleAnalyze(io, options, command) {
132
132
  lines.push(`${value.reused ? "Reused" : "Saved"} ${value.status} analysis: ${value.artifactPath}`);
133
133
  if (value.executionReceiptPath)
134
134
  lines.push(`Execution receipt: ${value.executionReceiptPath}`);
135
+ if (value.rejectedOutputPath)
136
+ lines.push(`Rejected output, kept locally for diagnosis: ${value.rejectedOutputPath}`);
135
137
  if (value.usage) {
136
138
  lines.push(`Recorded attempt usage${value.usage.usageComplete ? "" : " (incomplete)"}: ${value.usage.inputTokens ?? "unknown"} input tokens, ${value.usage.outputTokens ?? "unknown"} output tokens.`);
137
139
  lines.push(`Estimated attempt cost: ${value.usage.estimatedCostUsd === null ? "unknown" : `$${value.usage.estimatedCostUsd}`}.`);
@@ -152,7 +154,7 @@ async function handleAnalyzeList(io, options, command) {
152
154
  const prepared = await resolveRunPath(await resolvePhysicalCwd(options.cwd), options.run).catch(() => null);
153
155
  const versions = prepared ? await listAnalyses(prepared) : [];
154
156
  const executions = prepared
155
- ? await listStudyAnalysisExecutions(prepared)
157
+ ? await listAnalysisExecutions(prepared)
156
158
  : { receipts: [], warnings: [] };
157
159
  const result = {
158
160
  schema: "humanish.analysis-history.v1",
@@ -1,6 +1,7 @@
1
1
  import { resolve } from "node:path";
2
2
  import { Command } from "commander";
3
3
  import { COMMS_PROVIDERS, saveCommsConnection } from "../../comms/connections.js";
4
+ import { catchTokenRefusal } from "../../comms/external-evidence.js";
4
5
  import { readCommsSetup } from "../../comms/setup.js";
5
6
  import { checkCommsConnection, configureCommsLab } from "../../comms/setup.js";
6
7
  import { inspectCommsRecovery, recoverCommsReceiving } from "../../comms/receiving-recovery.js";
@@ -73,7 +74,7 @@ export function registerCommsCommands(parent, io) {
73
74
  .summary("Run the adopter-hosted email catch.")
74
75
  .option("--port <port>", "Port for capture + inbox (default 8025).", String(DEFAULT_SANDBOX_CATCH_PORT))
75
76
  .option("--dir <path>", "Directory for the deliveries log and rendered inbox.", ".humanish/comms-catch")
76
- .option("--token <value>", "Require this bearer token on GET /deliveries (recommended when reachable off-host).")
77
+ .option("--token <value>", "Require this bearer token, at least 16 characters, on GET /deliveries (recommended when reachable off-host).")
77
78
  .option("--smtp-port <port>", "Also capture SMTP mail on 127.0.0.1:<port>. Point your app's SMTP transport here.")
78
79
  .option("--inbox-port <port>", "Also serve a READ-ONLY inbox listener on 0.0.0.0:<port>, so a persona on another machine can open /inbox. Without it the catch stays loopback-only.")
79
80
  .option("--recipient <address>", "Only render mail sent to this address (repeatable). Default: render whatever the app actually mailed.", (value, previous) => [...(previous ?? []), value])
@@ -178,6 +179,12 @@ async function handleCommsRecover(io, options, command) {
178
179
  }
179
180
  }
180
181
  async function handleCommsCatch(io, options) {
182
+ const tokenRefusal = catchTokenRefusal(options.token);
183
+ if (tokenRefusal !== undefined) {
184
+ io.writeErr(`--token: ${tokenRefusal} The token guards GET /deliveries, and runs scrub it from their warnings.\n`);
185
+ io.setExitCode(2);
186
+ return;
187
+ }
181
188
  const port = Number.parseInt(options.port, 10);
182
189
  if (!Number.isInteger(port) || port <= 0 || port > 65_534) {
183
190
  io.writeErr("--port must be an integer between 1 and 65534.\n");
@@ -1,5 +1,4 @@
1
1
  import { Command } from "commander";
2
- import type { RunLabProvenance } from "../../run/status.js";
3
2
  import type { LabConfig } from "../../lab/types.js";
4
3
  import { type CliIo, type LabCommandOptions } from "../io.js";
5
4
  import type { RouteRun } from "./lab-route-run.js";
@@ -7,7 +6,6 @@ interface ComputerUseRouteArgs {
7
6
  command: Command;
8
7
  io: CliIo;
9
8
  config: LabConfig;
10
- labProvenance?: RunLabProvenance;
11
9
  mode: "run" | "watch";
12
10
  options: LabCommandOptions;
13
11
  }
@@ -7,6 +7,7 @@ import { serveObserver } from "../../observer/render.js";
7
7
  import { startExposedObserver, validateExposure } from "../../observer/exposure.js";
8
8
  import { ServeTunnelError } from "../../observer/tunnel.js";
9
9
  import { cliAnalysisOptions } from "./analysis-signals.js";
10
+ import { onRunShutdown } from "./run-signals.js";
10
11
  import { parseLabCount, parseParticipantIds, parseObserverPort, wantsJson, writeResult, } from "../io.js";
11
12
  import { exposureRequestFromOptions, followObserver, planObserver, showObserver, staticObserverOpen, withObserverServer, } from "../observer-follow.js";
12
13
  import { formatCuaLabHuman } from "./lab-format.js";
@@ -29,6 +30,7 @@ export function computerUseRouteRun(args) {
29
30
  tunnel: undefined,
30
31
  exposeWarnings: [],
31
32
  publicTarget: undefined,
33
+ releaseShutdown: undefined,
32
34
  };
33
35
  return {
34
36
  options: cuaRunOptions(args, settings, prepared, live),
@@ -37,7 +39,12 @@ export function computerUseRouteRun(args) {
37
39
  if (outcome.route !== "computer-use") {
38
40
  throw new Error(`Expected the computer-use route, got ${outcome.route}.`);
39
41
  }
40
- await reportCuaRun(args, prepared, outcome.result, live);
42
+ try {
43
+ await reportCuaRun(args, prepared, outcome.result, live);
44
+ }
45
+ finally {
46
+ live.releaseShutdown?.();
47
+ }
41
48
  },
42
49
  };
43
50
  }
@@ -66,15 +73,15 @@ function resolveCuaSettings(args) {
66
73
  mode: args.mode,
67
74
  wantsMachine,
68
75
  });
69
- const participantIds = parseParticipantIds(args.options.lanes);
76
+ const participantIds = parseParticipantIds(args.options.participants);
70
77
  if (participantIds.length > 0 && !args.options.rerunFailedFrom) {
71
- args.io.writeErr("error: --lanes requires --rerun-failed-from.\n");
78
+ args.io.writeErr("error: --participants requires --rerun-failed-from.\n");
72
79
  args.io.setExitCode(2);
73
80
  return undefined;
74
81
  }
75
- const count = parseLabCount(args.options.count ?? args.options.sims, args.config.actors[0]?.count ?? 1);
82
+ const count = parseLabCount(args.options.count, args.config.actors[0]?.count ?? 1);
76
83
  if (count === null) {
77
- args.io.writeErr("error: --count/--sims must be a positive integer.\n");
84
+ args.io.writeErr("error: --count must be a positive integer.\n");
78
85
  args.io.setExitCode(2);
79
86
  return undefined;
80
87
  }
@@ -122,7 +129,6 @@ function cuaRunOptions(args, settings, prepared, live) {
122
129
  return {
123
130
  ...cliAnalysisOptions(args.io),
124
131
  cwd: args.options.cwd,
125
- ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
126
132
  // A followed watch opens the served Observer (or prints the phone target under --expose), so
127
133
  // its static render never opens. A non-follow watch opens what its plan says, once. Run mode
128
134
  // keeps the static open.
@@ -153,20 +159,24 @@ function cuaRunOptions(args, settings, prepared, live) {
153
159
  }),
154
160
  };
155
161
  }
162
+ /** Closes the loopback server and any tunnel the watch attached. Safe to call twice. */
163
+ async function closeLiveAttachment(io, live) {
164
+ const { server, tunnel } = live;
165
+ live.server = null;
166
+ live.tunnel = undefined;
167
+ await server?.close().catch((cleanupError) => {
168
+ io.writeErr(`watch cleanup failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}\n`);
169
+ });
170
+ await tunnel?.close().catch(() => undefined);
171
+ }
156
172
  /**
157
173
  * Tears down the loopback server and any tunnel started inside onObserverReady, then reports a
158
174
  * tunnel startup failure or rethrows. The sandbox is created after onObserverReady returns, so a
159
175
  * tunnel failure cannot orphan one.
160
176
  */
161
177
  async function closeLiveAfterRunError(args, settings, live, error) {
162
- await live.server?.close().catch((cleanupError) => {
163
- args.io.writeErr(`watch cleanup failed: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}\n`);
164
- });
165
- live.server = null;
166
- if (live.tunnel) {
167
- await live.tunnel.close().catch(() => undefined);
168
- live.tunnel = undefined;
169
- }
178
+ await closeLiveAttachment(args.io, live);
179
+ live.releaseShutdown?.();
170
180
  if (error instanceof ServeTunnelError) {
171
181
  refuseCua(args, settings.dryRun, error.code, error.message);
172
182
  return;
@@ -182,6 +192,8 @@ async function attachLiveObserver(io, settings, exposure, live, observer) {
182
192
  port: settings.port,
183
193
  exposed: exposure.exposed,
184
194
  });
195
+ // A signal that stops the run closes the server and any tunnel before the process exits.
196
+ live.releaseShutdown ??= onRunShutdown(() => closeLiveAttachment(io, live));
185
197
  }
186
198
  if (exposure.exposed) {
187
199
  const activeServer = live.server;
@@ -1,5 +1,4 @@
1
1
  import { Command } from "commander";
2
- import type { RunLabProvenance } from "../../run/status.js";
3
2
  import type { LabConfig } from "../../lab/types.js";
4
3
  import { type CliIo, type LabCommandOptions } from "../io.js";
5
4
  import type { RouteRun } from "./lab-route-run.js";
@@ -8,12 +7,11 @@ interface PreviewRouteArgs {
8
7
  io: CliIo;
9
8
  lab: string;
10
9
  config: LabConfig;
11
- labProvenance?: RunLabProvenance;
12
10
  mode: "run" | "watch";
13
11
  options: LabCommandOptions;
14
12
  }
15
13
  /**
16
- * The preview route's CLI setup: the sim count and Observer plan, its runLab options, and how it
14
+ * The preview route's CLI setup: the participant count and Observer plan, its runLab options, and how it
17
15
  * presents the outcome. Undefined when setup has already written its own result.
18
16
  */
19
17
  export declare function previewRouteRun(args: PreviewRouteArgs): RouteRun | undefined;
@@ -2,11 +2,11 @@ import { Command } from "commander";
2
2
  import { formatRunHuman, parseLabCount, writeResult, } from "../io.js";
3
3
  import { planObserver, showObserver, staticObserverOpen } from "../observer-follow.js";
4
4
  /**
5
- * The preview route's CLI setup: the sim count and Observer plan, its runLab options, and how it
5
+ * The preview route's CLI setup: the participant count and Observer plan, its runLab options, and how it
6
6
  * presents the outcome. Undefined when setup has already written its own result.
7
7
  */
8
8
  export function previewRouteRun(args) {
9
- const participantCount = parseLabCount(args.options.sims, args.config.actors[0]?.count ?? 4);
9
+ const participantCount = parseLabCount(args.options.count, args.config.actors[0]?.count ?? 4);
10
10
  if (participantCount === null) {
11
11
  const result = {
12
12
  schema: "humanish.run-result.v1",
@@ -15,7 +15,7 @@ export function previewRouteRun(args) {
15
15
  warnings: [],
16
16
  error: {
17
17
  code: "HUMANISH_INVALID_SIM_COUNT",
18
- message: "--sims must be a positive integer.",
18
+ message: "--count must be a positive integer.",
19
19
  },
20
20
  };
21
21
  writeResult(args.command, args.io, result, formatRunHuman);
@@ -42,7 +42,6 @@ export function previewRouteRun(args) {
42
42
  return {
43
43
  options: {
44
44
  cwd: args.options.cwd,
45
- ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
46
45
  count: participantCount,
47
46
  ...(args.options.dryRun === undefined ? {} : { dryRun: args.options.dryRun }),
48
47
  ...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
@@ -1,8 +1,8 @@
1
- import { type LabOutcome, type RunLabOptions } from "../../run-lab.js";
1
+ import { type InternalRunLabOptions, type LabOutcome } from "../../run-lab.js";
2
2
  import type { LabConfig } from "../../lab/types.js";
3
3
  import type { LoadedAdapterScorer } from "./lab-scorer.js";
4
4
  export interface RouteRun {
5
- readonly options: RunLabOptions;
5
+ readonly options: InternalRunLabOptions;
6
6
  present(outcome: LabOutcome): Promise<void>;
7
7
  /** Handles an error runLab threw, and rethrows any it does not handle. */
8
8
  onRunError?(error: unknown): Promise<void>;
@@ -10,8 +10,10 @@ export interface RouteRun {
10
10
  /**
11
11
  * Plans the lab with a route's options, then presents the refusal or the run. `beforeRun` runs
12
12
  * only for a plan that will run: it loads the scorer, or writes its own refusal and returns
13
- * undefined, so a refused lab never imports the scorer's host code.
13
+ * undefined, so a refused lab never imports the scorer's host code. `afterRun` runs once runLab
14
+ * has returned or thrown, before presentation, which may hold its own signal handlers (watch's
15
+ * Observer and tunnel).
14
16
  */
15
17
  export declare function runRoute(config: LabConfig, run: RouteRun, beforeRun?: () => Promise<{
16
18
  scorer?: LoadedAdapterScorer;
17
- } | undefined>): Promise<void>;
19
+ } | undefined>, afterRun?: () => void): Promise<void>;
@@ -4,9 +4,11 @@ import { prepareLab } from "../../run-lab.js";
4
4
  /**
5
5
  * Plans the lab with a route's options, then presents the refusal or the run. `beforeRun` runs
6
6
  * only for a plan that will run: it loads the scorer, or writes its own refusal and returns
7
- * undefined, so a refused lab never imports the scorer's host code.
7
+ * undefined, so a refused lab never imports the scorer's host code. `afterRun` runs once runLab
8
+ * has returned or thrown, before presentation, which may hold its own signal handlers (watch's
9
+ * Observer and tunnel).
8
10
  */
9
- export async function runRoute(config, run, beforeRun = () => Promise.resolve({})) {
11
+ export async function runRoute(config, run, beforeRun = () => Promise.resolve({}), afterRun = () => undefined) {
10
12
  let outcome;
11
13
  try {
12
14
  const prepared = await prepareLab(config, run.options);
@@ -22,10 +24,12 @@ export async function runRoute(config, run, beforeRun = () => Promise.resolve({}
22
24
  }
23
25
  }
24
26
  catch (error) {
27
+ afterRun();
25
28
  if (run.onRunError === undefined)
26
29
  throw error;
27
30
  await run.onRunError(error);
28
31
  return;
29
32
  }
33
+ afterRun();
30
34
  await run.present(outcome);
31
35
  }
@@ -1,5 +1,4 @@
1
1
  import { Command } from "commander";
2
- import type { RunLabProvenance } from "../../run/status.js";
3
2
  import type { LabConfig } from "../../lab/types.js";
4
3
  import { type CliIo, type LabCommandOptions } from "../io.js";
5
4
  import type { RouteRun } from "./lab-route-run.js";
@@ -7,7 +6,6 @@ interface ScriptedRouteArgs {
7
6
  command: Command;
8
7
  io: CliIo;
9
8
  config: LabConfig;
10
- labProvenance?: RunLabProvenance;
11
9
  mode: "run" | "watch";
12
10
  options: LabCommandOptions;
13
11
  }
@@ -24,7 +24,6 @@ export function scriptedRouteRun(args) {
24
24
  options: {
25
25
  ...cliAnalysisOptions(args.io),
26
26
  cwd: args.options.cwd,
27
- ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
28
27
  open: observerOpen(args.mode, finishedPlan, shouldOpen),
29
28
  ...(args.options.dryRun === undefined ? {} : { dryRun: args.options.dryRun }),
30
29
  ...(args.options.runId === undefined ? {} : { runId: args.options.runId }),
@@ -1,5 +1,4 @@
1
1
  import { Command } from "commander";
2
- import type { RunLabProvenance } from "../../run/status.js";
3
2
  import type { LabConfig } from "../../lab/types.js";
4
3
  import { type CliIo, type LabCommandOptions } from "../io.js";
5
4
  import type { RouteRun } from "./lab-route-run.js";
@@ -7,7 +6,6 @@ interface SharedWorldRouteArgs {
7
6
  command: Command;
8
7
  io: CliIo;
9
8
  config: LabConfig;
10
- labProvenance?: RunLabProvenance;
11
9
  mode: "run" | "watch";
12
10
  options: LabCommandOptions;
13
11
  }
@@ -63,7 +63,6 @@ export function sharedWorldRouteRun(args) {
63
63
  options: {
64
64
  ...cliAnalysisOptions(args.io),
65
65
  cwd: args.options.cwd,
66
- ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
67
66
  open: wantsFollow
68
67
  ? false
69
68
  : finishedPlan === undefined
@@ -1,5 +1,4 @@
1
1
  import { Command } from "commander";
2
- import type { RunLabProvenance } from "../../run/status.js";
3
2
  import type { LabConfig } from "../../lab/types.js";
4
3
  import { type CliIo, type LabCommandOptions } from "../io.js";
5
4
  import type { RouteRun } from "./lab-route-run.js";
@@ -7,7 +6,6 @@ interface TerminalRouteArgs {
7
6
  command: Command;
8
7
  io: CliIo;
9
8
  config: LabConfig;
10
- labProvenance?: RunLabProvenance;
11
9
  mode: "run" | "watch";
12
10
  options: LabCommandOptions;
13
11
  }
@@ -24,7 +24,6 @@ export function terminalRouteRun(args) {
24
24
  options: {
25
25
  ...cliAnalysisOptions(args.io),
26
26
  cwd: args.options.cwd,
27
- ...(args.labProvenance === undefined ? {} : { lab: args.labProvenance }),
28
27
  open: observerOpen(args.mode, finishedPlan, shouldOpen),
29
28
  ...(args.options.dryRun === undefined ? {} : { dryRun: args.options.dryRun }),
30
29
  ...(args.options.runId === undefined ? {} : { runId: args.options.runId }),