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,38 +1,39 @@
1
- // The CONCURRENT shared-world lab backend (#164 phase 2): N persona lanes drive ONE shared,
2
- // mutable service plane SIMULTANEOUSLY — the actual leverage of a sim. A recomposition of shipped
1
+ // The concurrent shared-world lab backend (#164 phase 2): N persona participants drive one shared,
2
+ // mutable service plane at the same time. A recomposition of shipped
3
3
  // pieces + the getHost wrapper:
4
4
  //
5
- // - ONE SUBJECT sandbox: provisionCloneSubject ONCE (clone+install+build+seed) + serve on
5
+ // - One subject sandbox: provisionCloneSubject once (clone+install+build+seed) + serve on
6
6
  // 0.0.0.0, exposed via getHost(port) → a tokenless reachable URL (the headless service host;
7
7
  // no GUI seat).
8
- // - N ACTOR desktop sandboxes: fan-out's runCuaParticipant machinery (per-lane device/persona, by-id
8
+ // - N actor desktop sandboxes: fan-out's runCuaParticipant machinery (per-participant device/persona, by-id
9
9
  // teardown) bounded by execution.concurrency, each browser pointed at the getHost URL —
10
- // driving the shared service AT THE SAME TIME. INDEPENDENT (FIX-11): no pipeline gate, no
10
+ // driving the shared service at the same time. Independent: no pipeline gate, no
11
11
  // fail-fast — one actor's failure must not block the swarm or corrupt the "M of N" outcomes.
12
12
  // - A background prober snapshots the subject DB checkpoint digests on a cadence → a stateSeries
13
13
  // of the shared world evolving under load.
14
- // - ALL N+1 sandboxes torn down BY exact id in a finally — NEVER Sandbox.list.
14
+ // - All N+1 sandboxes torn down by exact id in a finally, never through Sandbox.list.
15
15
  //
16
- // HONEST ATTRIBUTION (verify-enforced, doctrine-audit fixes incorporated): the bundle declares
17
- // attributionClass: shared-world + a CONCURRENT humanish.shared-world.v1 block (topologyMode
18
- // "concurrent"; laneWindows + stateSeries + outcomes; NO timeline) whose attributionLimits drop
16
+ // Attribution (enforced by verify): the bundle declares
17
+ // attributionClass: shared-world + a concurrent humanish.shared-world.v1 block (topologyMode
18
+ // "concurrent"; laneWindows + stateSeries + outcomes; no timeline) whose attributionLimits drop
19
19
  // `sequential-only`/`no-concurrent-races` and add `concurrent`,
20
20
  // `best-effort-causal-attribution`, `non-deterministic-shared-state`,
21
21
  // `window-and-snapshot-granularity`, `contention-observed-not-proven-safe`,
22
- // `state-change-not-isolated-to-actors`. laneWindows + stateSeries are INDEPENDENT series with NO
22
+ // `state-change-not-isolated-to-actors`. laneWindows + stateSeries are independent series with no
23
23
  // per-delta→actor field — causation under concurrency is structurally inexpressible.
24
24
  //
25
- // CAPABILITY vs PROOF (FIX-1): the deterministic $0 gate proves the PLUMBING + the honesty
25
+ // Capability and proof: the deterministic $0 gate proves the plumbing + the honesty
26
26
  // contract — the real mapWithConcurrency produces genuinely overlapping laneWindows (a rendezvous
27
- // latch in the fake session forces two lane fns in-flight while the REAL orchestrator clock
27
+ // latch in the fake session forces two participant fns in-flight while the real orchestrator clock
28
28
  // measures the windows). Every generated bundle describes only its own observations; no one run
29
29
  // establishes scale, repeatability, or adopter-harness replacement.
30
30
  //
31
- // Synthetic-subject (FIX-3): a getHost URL is internet-reachable for the run, so this route is
32
- // synthetic-seeded-subjects ONLY. Verify fail-closes on subject.state.provenance != "seeded" and
31
+ // Synthetic subject: a getHost URL is internet-reachable for the run, so this route is for
32
+ // synthetic seeded subjects only. Verify fail-closes on subject.state.provenance != "seeded" and
33
33
  // requires the author attestation subject.exposure: synthetic. This is author-trust + a provenance
34
- // gate, NOT a no-real-data guarantee (humanish cannot tell synthetic from real data).
34
+ // gate; humanish cannot tell synthetic from real data, so it makes no claim about real data.
35
35
  import path from "node:path";
36
+ import { missingKeys, missingSubjectEnv } from "../../lab/requirements.js";
36
37
  import { completeAutomaticAnalysis } from "../../analysis/automatic-completion.js";
37
38
  import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
38
39
  import { scrubLiterals } from "../../evidence/redaction.js";
@@ -46,7 +47,8 @@ import { localAgentRefusal } from "../../actors/local-agent/readiness.js";
46
47
  import { runProvisionedPlane } from "./provisioned.js";
47
48
  import { concurrentLabFailure, finishConcurrentRun } from "./result.js";
48
49
  import { prepareConcurrentRun } from "./setup.js";
49
- import { sharedWorldInputWithScorer } from "../../lab/route-inputs.js";
50
+ import { browserRouteScorer } from "../../lab/adapter-scorer-loader.js";
51
+ import { withLateScorer } from "../../lab/route-inputs.js";
50
52
  import {} from "./types.js";
51
53
  import { rosterOf } from "../../lab/parse/actors.js";
52
54
  /** The shared-world code for each local-agent refusal, kind for kind with computer-use. */
@@ -62,12 +64,11 @@ const LOCAL_AGENT_REFUSAL_CODES = {
62
64
  * run and its analysis.
63
65
  */
64
66
  export async function runConcurrentSharedWorld(options) {
65
- const { config, dryRun, lab, ...input } = options;
67
+ const { config, dryRun, ...input } = options;
66
68
  // planSharedWorldLab makes every configuration refusal, in the order this route always has.
67
69
  const planned = planSharedWorldLab(config, {
68
70
  dryRun,
69
- ...(lab === undefined ? {} : { lab }),
70
- hooks: input.hooks ?? {},
71
+ hasRunSession: input.deps?.runSession !== undefined,
71
72
  });
72
73
  if (planned.ok)
73
74
  return runSharedWorldPlan(planned.plan, input, config);
@@ -90,7 +91,7 @@ export function sharedWorldLabRefusal(options, refusal) {
90
91
  });
91
92
  // A refusal starts no run, so a declared or default analysis is recorded as skipped.
92
93
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
93
- return completeAutomaticAnalysis(fail(refusal.code, refusal.message, refusal.actor), undefined, analysis.ok ? analysis.config : undefined, options.automaticAnalysis, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
94
+ return completeAutomaticAnalysis(fail(refusal.code, refusal.message, refusal.actor), undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
94
95
  }
95
96
  /**
96
97
  * runLab's step for a shared-world plan. It runs a live plan's local checks (the keys, a local
@@ -103,11 +104,11 @@ export async function admitSharedWorldPlan(plan, input, config) {
103
104
  return { ok: false, outcome: sharedWorldOutcome(refused) };
104
105
  return {
105
106
  ok: true,
106
- run: async (scorer) => sharedWorldOutcome(await runAdmittedSharedWorldRun(plan, sharedWorldInputWithScorer(input, scorer), config)),
107
+ run: async (scorer) => sharedWorldOutcome(await runAdmittedSharedWorldRun(plan, withLateScorer(input, scorer, browserRouteScorer), config)),
107
108
  };
108
109
  }
109
110
  function sharedWorldOutcome(result) {
110
- return { route: "shared-world", backend: "concurrent-shared-world", result };
111
+ return { route: "shared-world", result };
111
112
  }
112
113
  /** Run a shared-world plan: its local checks, then the run. */
113
114
  export async function runSharedWorldPlan(plan, input, config) {
@@ -122,18 +123,13 @@ export async function runSharedWorldPlan(plan, input, config) {
122
123
  async function admitSharedWorldRun(plan, input) {
123
124
  if (plan.dryRun)
124
125
  return undefined;
125
- const env = input.hooks?.env ?? process.env;
126
- const subjectEnvNames = plan.plane.kind === "provisioned" ? plan.plane.subject.env : [];
126
+ const env = input.env ?? process.env;
127
127
  const fail = (code, message) => completeSharedWorldAnalysis(plan, input, sharedWorldFailure(plan, input)(code, message, sharedWorldDescriptorOf(plan.actor).id), undefined);
128
- // OPENAI_API_KEY drives an openai brain's seats and the external-public plane's lobby-code
129
- // reader; a local-agent brain's seats run on the operator's signed-in agent instead.
130
- const openaiKeyNeeded = plan.brain.kind === "openai" || plan.plane.kind === "external-public";
131
- const missingKeys = [
132
- ...(env.OPENAI_API_KEY?.trim() || !openaiKeyNeeded ? [] : ["OPENAI_API_KEY"]),
133
- ...(env.E2B_API_KEY?.trim() ? [] : ["E2B_API_KEY"]),
134
- ];
135
- if (missingKeys.length > 0) {
136
- return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING", `Live concurrent shared-world labs need ${missingKeys.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missingKeys, env)}`);
128
+ // The plan lists OPENAI_API_KEY for an openai brain's seats and the external-public plane's
129
+ // lobby-code reader; a local-agent brain's seats run on the operator's signed-in agent instead.
130
+ const missing = missingKeys(plan.requirements, env);
131
+ if (missing.length > 0) {
132
+ return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING", `Live concurrent shared-world labs need ${missing.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missing, env)}`);
137
133
  }
138
134
  if (plan.brain.kind === "local-agent") {
139
135
  // A missing or signed-out agent found after the seats' desktops are paid for is the same
@@ -142,9 +138,9 @@ async function admitSharedWorldRun(plan, input) {
142
138
  if (refusal)
143
139
  return fail(LOCAL_AGENT_REFUSAL_CODES[refusal.kind], refusal.message);
144
140
  }
145
- const missingSubjectEnv = subjectEnvNames.filter((name) => !env[name]?.trim());
146
- if (missingSubjectEnv.length > 0) {
147
- return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING", `subject.env declares ${missingSubjectEnv.join(", ")} but the environment does not provide ${missingSubjectEnv.length === 1 ? "it" : "them"} (pass via --env-file; values are never persisted).`);
141
+ const unsetSubjectEnv = missingSubjectEnv(plan.requirements, env);
142
+ if (unsetSubjectEnv.length > 0) {
143
+ return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING", `subject.env declares ${unsetSubjectEnv.join(", ")} but the environment does not provide ${unsetSubjectEnv.length === 1 ? "it" : "them"} (pass via --env-file; values are never persisted).`);
148
144
  }
149
145
  return undefined;
150
146
  }
@@ -160,7 +156,7 @@ function runAdmittedSharedWorldRun(plan, input, config) {
160
156
  });
161
157
  }
162
158
  function completeSharedWorldAnalysis(plan, input, result, finished) {
163
- return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input.automaticAnalysis, {
159
+ return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
164
160
  ...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
165
161
  preferLargerOutput: plan.analysis?.preferLargerOutput === true,
166
162
  });
@@ -180,8 +176,8 @@ function sharedWorldFailure(plan, input) {
180
176
  async function runPlanInScope(plan, input, config, scope) {
181
177
  const { dryRun } = plan;
182
178
  const requestedCwd = path.resolve(input.cwd);
183
- const hooks = input.hooks ?? {};
184
- const env = hooks.env ?? process.env;
179
+ const deps = input.deps ?? {};
180
+ const env = input.env ?? process.env;
185
181
  const fail = sharedWorldFailure(plan, input);
186
182
  const descriptor = sharedWorldDescriptorOf(plan.actor);
187
183
  const planeClass = plan.plane.kind === "external-public" ? "external-public" : "provisioned-getHost";
@@ -194,7 +190,7 @@ async function runPlanInScope(plan, input, config, scope) {
194
190
  const subjectRepo = plan.residual.subject.repos?.[0] ?? "";
195
191
  const subjectEnvNames = [...(subject?.env ?? [])];
196
192
  const checkpoints = [...(subject?.state.checkpoint ?? [])];
197
- const runSession = hooks.runSession ?? descriptor.runSession;
193
+ const runSession = deps.runSession ?? descriptor.runSession;
198
194
  const openaiApiKey = env.OPENAI_API_KEY?.trim() ?? "";
199
195
  const e2bApiKey = env.E2B_API_KEY?.trim() ?? "";
200
196
  const knownSecretValues = [
@@ -212,7 +208,7 @@ async function runPlanInScope(plan, input, config, scope) {
212
208
  input,
213
209
  config,
214
210
  requestedCwd,
215
- hooks,
211
+ deps,
216
212
  env,
217
213
  descriptor,
218
214
  planeClass,
@@ -1,17 +1,18 @@
1
1
  import type { CuaActorDescriptor } from "../../actors/registry.js";
2
2
  import type { LabConfig, LabSubjectServe, LabSubjectStateCheckpoint } from "../../lab/types.js";
3
3
  import type { RunScope } from "../../run/run.js";
4
- import type { ConcurrentSharedWorldLabErrorCode, ConcurrentSharedWorldLabResult, ConcurrentSharedWorldPlaneClass, FinishFacts, LiveParticipants, PlaneContext, PlaneResults, PlaneSelection, SharedWorldLabHooks, SharedWorldRunInput } from "./types.js";
4
+ import type { ConcurrentSharedWorldLabErrorCode, ConcurrentSharedWorldLabResult, ConcurrentSharedWorldPlaneClass, FinishFacts, LiveParticipants, PlaneContext, PlaneResults, PlaneSelection, SharedWorldRunInput } from "./types.js";
5
+ import type { LabDeps } from "../../lab/lab-deps.js";
5
6
  import type { SharedWorldPlan } from "../../lab/plan-types.js";
6
7
  /** What validation derived from the lab, which setup reads. */
7
8
  interface AdmittedLab {
8
9
  plan: SharedWorldPlan;
9
10
  input: SharedWorldRunInput;
10
- /** Read by the computer-use lane runner, whose hooks and desktop setup take the whole config.
11
- * Seats, their count and their host and entry come from the plan's participants. */
11
+ /** Read for the subject's serve URL, which each seat's subject names. Seats, their count and
12
+ * their host and entry come from the plan's participants. */
12
13
  config: LabConfig;
13
14
  requestedCwd: string;
14
- hooks: SharedWorldLabHooks;
15
+ deps: LabDeps;
15
16
  env: Record<string, string | undefined>;
16
17
  descriptor: CuaActorDescriptor;
17
18
  planeClass: ConcurrentSharedWorldPlaneClass;
@@ -10,7 +10,7 @@ import { prepareEmailReceiving, prepareExternalComms, receivingSourceOf, subject
10
10
  import { declaredOriginDigestOf } from "./external-public.js";
11
11
  import { packSubjectTree } from "./provisioned.js";
12
12
  import { emptyPlaneResults } from "./result.js";
13
- import { buildParticipantSpecs, defaultSessionTimeoutMs } from "./seats.js";
13
+ import { buildParticipantSpecs, defaultSessionTimeoutMs } from "./participant-specs.js";
14
14
  import { planeStateOf } from "./plan.js";
15
15
  import path from "node:path";
16
16
  import { e2bRequestTimeoutMs } from "../../substrates/e2b/lifetime.js";
@@ -49,7 +49,7 @@ async function bindPhysicalProject(requestedCwd) {
49
49
  .physicalPath;
50
50
  }
51
51
  function startConcurrentRun(lab, cwd, scope) {
52
- const { plan, input, hooks } = lab;
52
+ const { plan, input, deps } = lab;
53
53
  return scope.startRun({
54
54
  cwd,
55
55
  runId: input.runId,
@@ -57,7 +57,7 @@ function startConcurrentRun(lab, cwd, scope) {
57
57
  mode: plan.dryRun ? "dry-run" : "live",
58
58
  lab: plan.lab,
59
59
  renderReview: renderConcurrentReviewMarkdown,
60
- observer: { open: input.open === true, render: hooks.renderObserverFn },
60
+ observer: { open: input.open === true, render: deps.renderObserver },
61
61
  });
62
62
  }
63
63
  /**
@@ -65,7 +65,7 @@ function startConcurrentRun(lab, cwd, scope) {
65
65
  * specs, comms, the packed tree and email receiving. Returns the refusal when one of them fails.
66
66
  */
67
67
  export async function prepareConcurrentRun(lab, scope) {
68
- const { plan, input, config, requestedCwd, hooks, env, descriptor, planeClass, fail } = lab;
68
+ const { plan, input, config, requestedCwd, deps, env, descriptor, planeClass, fail } = lab;
69
69
  const { runBudget, runSession, localTreeRoute, subjectEnvNames, publicRepo } = lab;
70
70
  const { openaiApiKey, e2bApiKey, knownSecretValues, scrubKnownValues } = lab;
71
71
  const { dryRun, concurrency } = plan;
@@ -73,17 +73,14 @@ export async function prepareConcurrentRun(lab, scope) {
73
73
  const warnings = [];
74
74
  // The comms catch and the packed tree are checked before the run starts, so a refusal leaves
75
75
  // no run directory. Neither spends: the probe is one request and packing runs on the host.
76
- const externalComms = await prepareExternalComms(plan.residual, planeClass, dryRun, warnings);
76
+ const externalComms = await prepareExternalComms(plan.residual, planeClass, dryRun, warnings, env);
77
77
  if (!externalComms.ok) {
78
- return {
79
- ok: false,
80
- result: fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE", externalComms.message),
81
- };
78
+ return { ok: false, result: fail(externalComms.code, externalComms.message) };
82
79
  }
83
80
  // Pack the working tree once per run, on the host, before any sandbox exists: a packing
84
81
  // failure fails the run closed without sandbox cost. Dry-run packs nothing.
85
82
  const packed = localTreeRoute && !dryRun
86
- ? await packSubjectTree(cwd, plan.residual, hooks, scrubKnownValues)
83
+ ? await packSubjectTree(cwd, plan.residual, deps, scrubKnownValues)
87
84
  : { ok: true, archive: undefined, buffer: undefined };
88
85
  if (!packed.ok) {
89
86
  return {
@@ -102,9 +99,9 @@ export async function prepareConcurrentRun(lab, scope) {
102
99
  const timeoutMs = plan.sessionTimeoutMs ?? defaultSessionTimeoutMs(plan);
103
100
  const requestTimeoutMs = e2bRequestTimeoutMs(env);
104
101
  const redactScreenshots = plan.residual.policies?.redactScreenshots === true;
105
- const timers = hooks.detachedTimers ?? {};
106
- const now = hooks.now ?? Date.now;
107
- const proberCadenceMs = hooks.proberCadenceMs ?? DEFAULT_PROBER_CADENCE_MS;
102
+ const timers = deps.detachedTimers ?? {};
103
+ const now = deps.now ?? Date.now;
104
+ const proberCadenceMs = deps.proberCadenceMs ?? DEFAULT_PROBER_CADENCE_MS;
108
105
  const seedDigest = seedRecipeDigest(planeStateOf(plan));
109
106
  const source = await buildRunSource({
110
107
  capturedAt: createdAt,
@@ -147,7 +144,7 @@ export async function prepareConcurrentRun(lab, scope) {
147
144
  input,
148
145
  config,
149
146
  descriptor,
150
- hooks,
147
+ deps,
151
148
  env,
152
149
  concurrency,
153
150
  runBudget,
@@ -155,6 +152,7 @@ export async function prepareConcurrentRun(lab, scope) {
155
152
  openaiApiKey,
156
153
  e2bApiKey,
157
154
  scrubKnownValues,
155
+ knownSecretValues,
158
156
  cwd,
159
157
  run,
160
158
  runId,
@@ -1,22 +1,19 @@
1
+ import type { LabDeps } from "../../lab/lab-deps.js";
2
+ import type { LabEvent } from "../../lab/run-lab-events.js";
3
+ import type { RunLabHomes } from "../../lab/run-lab-homes.js";
1
4
  import type { SharedWorldJudgment } from "../../run/judge.js";
2
- import type { CuaActorSessionOptions } from "../../actors/computer-use/actor.js";
3
- import type { CuaLoopResult } from "../../actors/computer-use/loop.js";
4
- import type { BrowserLabAdapterHooks } from "../../lab/adapter-extension.js";
5
- import type { SubjectPhaseEvent } from "../../subject/steps.js";
6
- import type { DetachedTimers } from "../../substrates/detached.js";
7
- import type { E2BDesktopModule, E2BDesktopSandbox } from "../../substrates/e2b/sdk.js";
8
- import type { AutomaticAnalysisHooks, AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
5
+ import type { BrowserScorer } from "../../lab/adapter-extension.js";
6
+ import type { AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
9
7
  import type { CuaActorDescriptor } from "../../actors/registry.js";
10
8
  import type { CommsReceivingRun } from "../../comms/receiving.js";
11
9
  import type { LabCommsEmail, LabCommsExternal, LabConfig } from "../../lab/types.js";
12
10
  import type { DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
13
- import type { ObserverResult, renderObserver } from "../../observer/render.js";
11
+ import type { ObserverResult } from "../../observer/render.js";
14
12
  import type { ObserverRuntimeStreamUrl } from "../../observer/run-routes.js";
15
- import type { RunBundle, RunScorerProvenance, RunSubjectProvenance, RunSubjectStateStepRecord } from "../../run/bundle.js";
13
+ import type { BundleRun, RunBundle, RunScorerProvenance, RunSubjectProvenance, RunSubjectStateStepRecord } from "../../run/bundle.js";
16
14
  import type { RunScope } from "../../run/run.js";
17
15
  import type { SharedWorldStateSnapshot } from "../../run/shared-world-evidence.js";
18
16
  import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
19
- import type { RunLabProvenance } from "../../run/status.js";
20
17
  import type { LiveTraceFlush } from "../computer-use/live-flush.js";
21
18
  import type { CuaParticipantDeps, DesktopParticipantRun, CuaRunBudget, ParticipantRunOutcome } from "../computer-use/types.js";
22
19
  import type { ProvisionedPlaneSetup } from "./provisioned.js";
@@ -28,9 +25,8 @@ export declare const CONCURRENT_SHARED_WORLD_PROVIDER_METADATA: {
28
25
  };
29
26
  export declare const CONCURRENT_ATTRIBUTION_LIMITS: readonly ["concurrent", "best-effort-causal-attribution", "non-deterministic-shared-state", "window-and-snapshot-granularity", "contention-observed-not-proven-safe", "state-change-not-isolated-to-actors"];
30
27
  export interface RunConcurrentSharedWorldLabOptions {
31
- automaticAnalysis?: AutomaticAnalysisHooks;
32
- /** Which manifest produced this run (#455); threaded into the status record + bundle. */
33
- lab?: RunLabProvenance;
28
+ /** Cancels post-run analysis only. */
29
+ analysisSignal?: AbortSignal;
34
30
  cwd: string;
35
31
  config: LabConfig;
36
32
  /** Resolved upstream (scenario.mode + CLI override); defaults safe (dry-run). */
@@ -40,27 +36,44 @@ export interface RunConcurrentSharedWorldLabOptions {
40
36
  onObserverReady?: (observer: ObserverResult & {
41
37
  ok: true;
42
38
  }) => Promise<void> | void;
43
- hooks?: SharedWorldLabHooks;
44
- /** Present only when the browser-route scorer hooks were CONFIG-DECLARED and loaded by the CLI
45
- * (#316); core-stamped onto the bundle as evidence. Absent for library callers. */
39
+ /** Keys and subject env for the run. Defaults to process.env. */
40
+ env?: Readonly<Record<string, string | undefined>>;
41
+ /**
42
+ * Runs after a sandbox exists and before anything is provisioned on it: the provisioned plane's
43
+ * subject sandbox, then each seat's desktop. The external-public plane has seats only.
44
+ */
45
+ prepareDesktop?: NonNullable<RunLabHomes["prepareDesktop"]>;
46
+ /** Awaited after a participant's live stream starts, and again after its sandbox is gone. */
47
+ onStream?: NonNullable<RunLabHomes["onStream"]>;
48
+ /** Reports subject phases to onEvent; built by normalizeRunLabOptions. */
49
+ emit?: (event: LabEvent) => void;
50
+ /** Test seams. */
51
+ deps?: LabDeps;
52
+ /** Scores the assembled evidence: `RunLabOptions.scorer`, or the scorer the CLI loads. */
53
+ scorer?: BrowserScorer;
54
+ /** Present only when the scorer was CONFIG-DECLARED and loaded by the CLI (#316);
55
+ * core-stamped onto the bundle as evidence. Absent for library callers. */
46
56
  scorerProvenance?: RunScorerProvenance;
47
57
  }
48
58
  /** What a shared-world run takes besides its plan. The plan carries the config, dry run and lab. */
49
59
  export type SharedWorldRunInput = Omit<RunConcurrentSharedWorldLabOptions, "config" | "dryRun" | "lab">;
50
- export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_CONFLICT" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING"
51
- /** A local-agent brain's CLI is not on PATH. */
60
+ export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING"
61
+ /** A local-agent brain's CLI is not on `PATH`. */
52
62
  | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_AGENT_MISSING"
53
63
  /** A local-agent brain's CLI is signed out, or could not report its sign-in status. */
54
64
  | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_AGENT_SIGNIN_REQUIRED"
55
65
  /** A dollar cap that cannot be priced: an unpriced model, or a ChatGPT-account Codex brain. */
56
66
  | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_UNPRICED_CAP" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_GETHOST_UNAVAILABLE" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT" | "HUMANISH_RUN_ID_IN_USE"
57
67
  /** A declared adopter-hosted comms catch (#328) did not answer as a humanish catch — fail closed
58
- * BEFORE any actor spend, since the funnel would silently collect nothing. */
59
- | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE";
68
+ * before any actor spend, since the funnel would silently collect nothing. */
69
+ | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE"
70
+ /** comms.email.external.authTokenEnv names a token shorter than MIN_CATCH_TOKEN_LENGTH or not
71
+ * well-formed Unicode (src/comms/external-evidence.ts). Refused before the catch is probed. */
72
+ | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_TOKEN_INVALID";
60
73
  /** The two plane classes of the concurrent shared-world route (#164 phase 2). */
61
74
  export type ConcurrentSharedWorldPlaneClass = "provisioned-getHost" | "external-public";
62
75
  export declare const EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS: readonly ["concurrent", "best-effort-causal-attribution", "non-deterministic-shared-state", "window-and-snapshot-granularity", "contention-observed-not-proven-safe", "state-change-not-isolated-to-actors", "external-public-plane", "operator-attested-target-not-harness-controlled", "no-synthetic-attestation", "no-authoritative-shared-state-proof", "concurrency-by-temporal-co-occupancy-only"];
63
- /** One persona's OUTCOME against the contended world (the "M of N" headline). */
76
+ /** One persona's outcome against the contended world (the "M of N" headline). */
64
77
  export interface ConcurrentSharedWorldParticipantResult {
65
78
  id: string;
66
79
  index: number;
@@ -96,7 +109,7 @@ export interface ConcurrentSharedWorldLabResult extends AutomaticAnalysisResult
96
109
  actor: string;
97
110
  topology: "shared-world";
98
111
  topologyMode: "concurrent";
99
- /** The DECLARED number of persona seats. */
112
+ /** The declared number of personas. */
100
113
  roleCount: number;
101
114
  /** Effective in-flight bound (execution.concurrency). */
102
115
  concurrency: number;
@@ -104,17 +117,17 @@ export interface ConcurrentSharedWorldLabResult extends AutomaticAnalysisResult
104
117
  runId: string;
105
118
  /** The harness-minted getHost URL the actors drove (tokenless; live only). */
106
119
  host?: string;
107
- /** The ONE subject sandbox lifecycle proof. */
120
+ /** The one subject sandbox lifecycle proof. */
108
121
  subjectSandbox?: {
109
122
  sandboxId: string;
110
123
  killed: boolean;
111
124
  };
112
125
  /** Whether ≥2 actor windows overlapped in time (proven concurrency; live only). */
113
126
  overlapProven?: boolean;
114
- /** Max lanes observed live at the same instant (live only) — the honest simultaneity number; a
115
- * 6-lane run capped at 3 reports 3 here, never 6 (#350). */
127
+ /** Max participants observed live at the same instant (live only) — the honest simultaneity number; a
128
+ * 6-participant run capped at 3 reports 3 here, never 6 (#350). */
116
129
  maxSimultaneousLanes?: number;
117
- /** Subject provenance (invariant 5): the ONE shared plane. */
130
+ /** Subject provenance (invariant 5): the one shared plane. */
118
131
  subject?: RunSubjectProvenance;
119
132
  roles: ConcurrentSharedWorldParticipantResult[];
120
133
  observer?: ObserverResult;
@@ -145,11 +158,12 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
145
158
  export interface PlaneContext {
146
159
  plan: SharedWorldPlan;
147
160
  input: SharedWorldRunInput;
148
- /** Read by the computer-use lane runner, whose hooks and desktop setup take the whole config.
149
- * Seats, their count and their host and entry come from the plan's participants. */
161
+ /** Read for the subject's serve URL, which each seat's subject names. Seats, their count and
162
+ * their host and entry come from the plan's participants. */
150
163
  config: LabConfig;
151
164
  descriptor: CuaActorDescriptor;
152
- hooks: SharedWorldLabHooks;
165
+ /** The run's test seams; empty outside tests. */
166
+ deps: LabDeps;
153
167
  env: Record<string, string | undefined>;
154
168
  concurrency: number;
155
169
  runBudget: CuaRunBudget | undefined;
@@ -157,6 +171,8 @@ export interface PlaneContext {
157
171
  openaiApiKey: string;
158
172
  e2bApiKey: string;
159
173
  scrubKnownValues: (text: string) => string;
174
+ /** The values scrubKnownValues removes. Real email receiving adds its secrets before seats start. */
175
+ knownSecretValues: readonly string[];
160
176
  cwd: string;
161
177
  run: StartedRun;
162
178
  runId: string;
@@ -176,7 +192,7 @@ export interface PlaneContext {
176
192
  }
177
193
  /**
178
194
  * What the seats feed while they run. A plane sets the attached Observer and starts the trace
179
- * flush; the runtime stream hooks append stream URLs; the orchestrator reads all three at finish.
195
+ * flush; each seat's onStream appends stream URLs; the orchestrator reads all three at finish.
180
196
  */
181
197
  export interface LiveParticipants {
182
198
  observer?: ObserverResult & {
@@ -195,14 +211,12 @@ export interface ExternalCommsWiring {
195
211
  export interface ConcurrentBundleArgs {
196
212
  /** The run's judgment (judgeSharedWorldRun over the other fields). */
197
213
  judgment: SharedWorldJudgment;
198
- /** Lab provenance for the bundle\'s own `lab` field (#455). */
199
- lab?: RunLabProvenance;
214
+ /** The run this bundle belongs to; the bundle head reads its id, mode, start and lab. */
215
+ run: BundleRun;
200
216
  plan: SharedWorldPlan;
201
217
  descriptor: CuaActorDescriptor;
202
- createdAt: string;
203
218
  dryRun: boolean;
204
219
  inProgress?: boolean;
205
- runId: string;
206
220
  source: RunBundle["source"];
207
221
  actorSpecs: DesktopParticipantRun[];
208
222
  actorResults: ActorRunResult[];
@@ -213,15 +227,15 @@ export interface ConcurrentBundleArgs {
213
227
  hostDigest?: string;
214
228
  /** Run-level digest-only comms-thread evidence path (humanish.comms-thread.v1), when a comms lab
215
229
  * captured mail into the subject sandbox's catch. Registered on the first persona stream (it is a
216
- * property of the ONE shared app, not of any single persona). */
230
+ * property of the one shared app, and belongs to no single persona). */
217
231
  commsArtifactPath?: string;
218
232
  /** #164 phase 2: the plane-class discriminator (default provisioned-getHost, byte-stable). */
219
233
  planeClass?: ConcurrentSharedWorldPlaneClass;
220
- /** external-public only: sha256-16 of the OBSERVED origin the seats converged on (the convergence
234
+ /** external-public only: sha256-16 of the observed origin the seats converged on (the convergence
221
235
  * proof — what the seats actually reached, tolerant of a declared->observed redirect). */
222
236
  publicOriginDigest?: string;
223
237
  /** external-public only: sha256-16 of the operator-DECLARED plane origin (evidence/reference only;
224
- * NOT asserted equal to the observed origin — a cross-origin redirect is normal and expected). */
238
+ * never asserted equal to the observed origin, since a cross-origin redirect is normal). */
225
239
  declaredOriginDigest?: string;
226
240
  /** external-public only: sha256-16 of the shared /lobby/CODE path all seats converged on. */
227
241
  lobbyConvergenceDigest?: string;
@@ -236,6 +250,8 @@ export interface PlaneResults {
236
250
  subjectCommit: string | undefined;
237
251
  subjectSandboxId: string | undefined;
238
252
  subjectKilled: boolean;
253
+ /** The subject sandbox's scrubbed release warning when its release is unconfirmed. */
254
+ subjectReleaseWarning: string | undefined;
239
255
  subjectDesktop: SubjectDesktopUsage | undefined;
240
256
  getHostUrl: string | undefined;
241
257
  publicOriginDigest: string | undefined;
@@ -262,93 +278,4 @@ export interface FinishFacts {
262
278
  stateSnapshots: SharedWorldStateSnapshot[];
263
279
  declaredOriginDigest: string | undefined;
264
280
  }
265
- /**
266
- * Library-level hooks mirroring CuaActorLabHooks — the DI seams that let CI drive the FULL
267
- * orchestration with fakes at $0/zero-network. The fake desktop module records create/kill BY id
268
- * and exposes NO `list` method (the by-id teardown rail is then provable by construction).
269
- */
270
- export interface SharedWorldLabHooks extends BrowserLabAdapterHooks {
271
- /** Lazy-load the E2B desktop module (tests inject a fake; default loadE2BDesktopModule). */
272
- loadDesktopModule?: () => Promise<E2BDesktopModule>;
273
- /**
274
- * Runs after a sandbox is created and before anything is provisioned on it. The provisioned
275
- * plane calls it for the subject sandbox with no lane, then for each seat's desktop with its lane;
276
- * the external-public plane calls it for the seats only.
277
- */
278
- prepareDesktop?: (desktop: E2BDesktopSandbox, lane?: {
279
- laneId: string;
280
- laneIndex: number;
281
- laneCount: number;
282
- }) => Promise<void>;
283
- /**
284
- * Awaited after a seat's live desktop stream starts. The URL carries an auth key and must never
285
- * be persisted. A rejection becomes a run warning, as on the computer-use route.
286
- */
287
- onRuntimeStreamReady?: (stream: {
288
- laneId: string;
289
- sandboxId: string;
290
- simId: string;
291
- streamId: string;
292
- url: string;
293
- }) => Promise<void> | void;
294
- /** Awaited after a seat's sandbox is gone, for seats whose stream started. Rejections are swallowed. */
295
- onRuntimeStreamEnded?: (stream: {
296
- laneId: string;
297
- simId: string;
298
- streamId: string;
299
- }) => Promise<void> | void;
300
- /** The per-seat computer-use session runner (default: the resolved actor descriptor's). */
301
- runSession?: (options: CuaActorSessionOptions) => Promise<CuaLoopResult>;
302
- /** The operator environment (keys + subject env values). Defaults to process.env. */
303
- env?: Record<string, string | undefined>;
304
- renderObserverFn?: typeof renderObserver;
305
- /** Injected clock/sleep for the detached-step polling (tests only). */
306
- detachedTimers?: DetachedTimers;
307
- /**
308
- * Subject-provisioning phase sink (mirrors CuaActorLabHooks.onPhase): one call per
309
- * started/completed boundary during the ONE shared-plane provision (clone route: clone, install,
310
- * build, serve start, ready, subject.state seed-step groups; local-tree route: upload, extract,
311
- * install, build, serve start, ready, seed-step groups - no clone phase). Defaults to one stderr
312
- * line per event. Override in tests to capture instead of writing to real stderr.
313
- */
314
- onPhase?: (event: SubjectPhaseEvent) => void;
315
- /**
316
- * CONCURRENT route only (#164 phase 2): the harness clock used to MEASURE each actor's laneWindow
317
- * [start,end] (default Date.now). The deterministic heart test does NOT override this — overlap is
318
- * produced by a rendezvous latch in the fake runSession + measured by the REAL clock (FIX-1), so
319
- * the windows are real, not injected. (A test may override only for non-overlap assertions.)
320
- */
321
- now?: () => number;
322
- /** CONCURRENT route only: the background stateSeries prober cadence (ms). Default 1000. */
323
- proberCadenceMs?: number;
324
- /**
325
- * EXTERNAL-PUBLIC concurrent route only (#164 phase 2): the host-first handoff barrier deadline
326
- * (ms). The host seat must surface a shared-session (/lobby/CODE) URL within this budget or the run
327
- * fails closed with HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT and no follower opens.
328
- * Default 120000 (also capped by execution.timeoutMs). Tests inject a short value to exercise the
329
- * fail-closed path deterministically.
330
- */
331
- handoffDeadlineMs?: number;
332
- /**
333
- * EXTERNAL-PUBLIC concurrent route only: the vision reader that extracts a /lobby/CODE off a seat's
334
- * screenshot frame (the CDP-independent handoff relay + per-seat convergence observation). Defaults to
335
- * the real single-frame OpenAI read (readLobbyCodeFromFrame). Tests inject a fake so the barrier's
336
- * handoff + convergence proof can be exercised deterministically without a live vision call.
337
- */
338
- readLobbyCodeFromFrame?: (frame: Buffer, apiKey: string) => Promise<string | undefined>;
339
- /**
340
- * Local-tree packing DI seam (tests only, no npm dependency needed to exercise the route):
341
- * defaults to createLocalTreeArchive(root, opts) plus a host-side read of the produced archive
342
- * file into an ArrayBuffer (the SAME default routes/computer-use/route.ts uses). Called ONCE per run, before
343
- * the ONE shared-plane sandbox is created, on the live local-tree route.
344
- */
345
- packLocalTree?: (args: {
346
- root: string;
347
- extraExclude?: string[];
348
- maxArchiveBytes?: number;
349
- }) => Promise<{
350
- archive: LocalTreeArchive;
351
- buffer: ArrayBuffer;
352
- }>;
353
- }
354
281
  export {};
@@ -5,7 +5,7 @@ export const CONCURRENT_SHARED_WORLD_PROVIDER_METADATA = {
5
5
  mode: "concurrent-shared-world-lab",
6
6
  tool: "humanish",
7
7
  };
8
- // The verify-enforced CONCURRENT attribution ceiling (FIX-5). Mirrored in
8
+ // The verify-enforced concurrent attribution ceiling. Mirrored in
9
9
  // verify/shared-world-concurrent.ts CONCURRENT_REQUIRED_LIMITS.
10
10
  export const CONCURRENT_ATTRIBUTION_LIMITS = [
11
11
  "concurrent",
@@ -16,7 +16,7 @@ export const CONCURRENT_ATTRIBUTION_LIMITS = [
16
16
  "state-change-not-isolated-to-actors",
17
17
  ];
18
18
  // EXTERNAL-PUBLIC plane class: the honest-downgrade attribution ceiling. The concurrent family
19
- // (an honest ceiling) PLUS the mandatory external-public disclosures — mirrored in the required
19
+ // (an honest ceiling) plus the mandatory external-public disclosures, mirrored in the required
20
20
  // set in verify/shared-world-concurrent.ts (CONCURRENT_ATTRIBUTION_LIMITS +
21
21
  // EXTERNAL_PUBLIC_EXTRA_LIMITS). Verify fails closed on a missing one.
22
22
  export const EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS = [