humanish 0.107.0 → 0.108.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 (521) hide show
  1. package/ARCHITECTURE.md +22 -17
  2. package/CHANGELOG.md +14 -0
  3. package/CONTEXT.md +51 -44
  4. package/README.md +145 -172
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-ui.js +1 -1
  14. package/dist/actors/codex/codex-admission.d.ts +91 -0
  15. package/dist/actors/codex/codex-admission.js +150 -0
  16. package/dist/actors/codex/restricted-executable.d.ts +4 -4
  17. package/dist/actors/codex/restricted-executable.js +8 -8
  18. package/dist/actors/codex/restricted-launch.d.ts +2 -1
  19. package/dist/actors/codex/restricted-launch.js +1 -1
  20. package/dist/actors/codex/restricted-participant.js +8 -6
  21. package/dist/actors/codex/restricted-policy.d.ts +2 -2
  22. package/dist/actors/codex/restricted-policy.js +2 -2
  23. package/dist/actors/codex/restricted-session.d.ts +2 -2
  24. package/dist/actors/codex/restricted-session.js +10 -5
  25. package/dist/actors/computer-use/actor.d.ts +16 -16
  26. package/dist/actors/computer-use/actor.js +2 -2
  27. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  28. package/dist/actors/computer-use/admission-limit.js +1 -1
  29. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  30. package/dist/actors/computer-use/loop/actions.js +10 -10
  31. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  32. package/dist/actors/computer-use/loop/backstop.js +14 -12
  33. package/dist/actors/computer-use/loop/ending.d.ts +5 -5
  34. package/dist/actors/computer-use/loop/ending.js +7 -7
  35. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/observation.js +9 -9
  37. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  39. package/dist/actors/computer-use/loop/session.js +3 -3
  40. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  41. package/dist/actors/computer-use/loop/spend.js +1 -1
  42. package/dist/actors/computer-use/loop/trace.js +9 -8
  43. package/dist/actors/computer-use/loop/types.d.ts +25 -23
  44. package/dist/actors/computer-use/loop/usage.js +2 -2
  45. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  46. package/dist/actors/computer-use/openai-context.js +214 -0
  47. package/dist/actors/computer-use/openai-provider.d.ts +11 -8
  48. package/dist/actors/computer-use/openai-provider.js +45 -34
  49. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  50. package/dist/actors/computer-use/openai-requests.js +82 -15
  51. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  52. package/dist/actors/computer-use/openai-wire.js +36 -34
  53. package/dist/actors/contract.d.ts +78 -43
  54. package/dist/actors/contract.js +29 -23
  55. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  56. package/dist/actors/local-agent/claude-session.js +10 -9
  57. package/dist/actors/local-agent/cli.d.ts +8 -6
  58. package/dist/actors/local-agent/cli.js +24 -28
  59. package/dist/actors/local-agent/readiness.d.ts +2 -2
  60. package/dist/actors/local-agent/readiness.js +4 -4
  61. package/dist/actors/reasoning-effort.js +6 -6
  62. package/dist/actors/registry.d.ts +10 -10
  63. package/dist/actors/registry.js +18 -17
  64. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  65. package/dist/actors/scripted-browser/actor.js +16 -16
  66. package/dist/actors/scripted-browser/browser-command.js +1 -1
  67. package/dist/actors/scripted-browser/steps.js +1 -1
  68. package/dist/actors/scripted-browser/types.d.ts +1 -1
  69. package/dist/actors/stop-conditions.d.ts +1 -1
  70. package/dist/analysis/codex-config.d.ts +6 -2
  71. package/dist/analysis/codex-config.js +22 -14
  72. package/dist/analysis/service.js +5 -5
  73. package/dist/cli/commands/analyze.js +19 -16
  74. package/dist/cli/commands/codex.js +9 -9
  75. package/dist/cli/commands/comms.js +54 -33
  76. package/dist/cli/commands/feedback.js +20 -21
  77. package/dist/cli/commands/lab-format.d.ts +5 -4
  78. package/dist/cli/commands/lab-format.js +35 -23
  79. package/dist/cli/commands/lab-route-computer-use.js +6 -7
  80. package/dist/cli/commands/lab-route-preview.js +4 -3
  81. package/dist/cli/commands/lab-route-shared-world.js +3 -3
  82. package/dist/cli/commands/lab-run.js +10 -11
  83. package/dist/cli/commands/lab-scorer.d.ts +2 -2
  84. package/dist/cli/commands/lab-scorer.js +1 -1
  85. package/dist/cli/commands/migrate.d.ts +4 -0
  86. package/dist/cli/commands/migrate.js +65 -0
  87. package/dist/cli/commands/observe.js +147 -108
  88. package/dist/cli/commands/run-command.d.ts +10 -0
  89. package/dist/cli/commands/run-command.js +85 -0
  90. package/dist/cli/commands/runs.js +137 -138
  91. package/dist/cli/commands/setup.d.ts +2 -2
  92. package/dist/cli/commands/setup.js +26 -21
  93. package/dist/cli/commands/study.d.ts +3 -0
  94. package/dist/cli/commands/study.js +182 -0
  95. package/dist/cli/commands/tui.d.ts +4 -4
  96. package/dist/cli/commands/tui.js +21 -21
  97. package/dist/cli/commands/watch.js +60 -75
  98. package/dist/cli/deprecations.d.ts +18 -0
  99. package/dist/cli/deprecations.js +48 -0
  100. package/dist/cli/doctor.d.ts +15 -5
  101. package/dist/cli/doctor.js +103 -48
  102. package/dist/cli/first-run-path.d.ts +12 -10
  103. package/dist/cli/first-run-path.js +30 -28
  104. package/dist/cli/io.d.ts +41 -6
  105. package/dist/cli/io.js +97 -22
  106. package/dist/cli/observer-follow.d.ts +2 -2
  107. package/dist/cli/observer-follow.js +5 -6
  108. package/dist/cli/orientation.d.ts +6 -3
  109. package/dist/cli/orientation.js +43 -39
  110. package/dist/cli/product-sentence.d.ts +6 -0
  111. package/dist/cli/product-sentence.js +6 -0
  112. package/dist/cli/program.d.ts +6 -1
  113. package/dist/cli/program.js +109 -40
  114. package/dist/cli/telemetry.d.ts +15 -15
  115. package/dist/cli/telemetry.js +48 -40
  116. package/dist/cli.js +1 -1
  117. package/dist/comms/capture-surface.d.ts +13 -12
  118. package/dist/comms/capture-surface.js +23 -22
  119. package/dist/comms/catch-host.d.ts +7 -7
  120. package/dist/comms/catch-host.js +14 -14
  121. package/dist/comms/email-catch.d.ts +3 -3
  122. package/dist/comms/email-catch.js +8 -8
  123. package/dist/comms/external-evidence.js +2 -2
  124. package/dist/comms/extract.js +2 -2
  125. package/dist/comms/fake-inbox.d.ts +2 -2
  126. package/dist/comms/fake-inbox.js +2 -2
  127. package/dist/comms/receiving-render.d.ts +1 -1
  128. package/dist/comms/receiving-render.js +2 -2
  129. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  130. package/dist/comms/sandbox-catch-script.js +6 -6
  131. package/dist/comms/sandbox-catch.d.ts +36 -37
  132. package/dist/comms/sandbox-catch.js +34 -35
  133. package/dist/comms/setup.js +42 -8
  134. package/dist/comms/thread-evidence.d.ts +1 -1
  135. package/dist/comms/thread-evidence.js +6 -6
  136. package/dist/comms/types.d.ts +6 -6
  137. package/dist/comms/types.js +3 -3
  138. package/dist/evidence/frame-signature.d.ts +1 -1
  139. package/dist/evidence/frame-signature.js +4 -4
  140. package/dist/evidence/redaction.d.ts +3 -3
  141. package/dist/evidence/redaction.js +4 -4
  142. package/dist/feedback/draft.js +36 -78
  143. package/dist/feedback/export-bundle.js +1 -1
  144. package/dist/feedback/export.d.ts +5 -1
  145. package/dist/feedback/export.js +7 -8
  146. package/dist/feedback/feedback.d.ts +2 -2
  147. package/dist/feedback/feedback.js +21 -3
  148. package/dist/guest/chromium-text.js +2 -2
  149. package/dist/guest/desktop-native.d.ts +1 -1
  150. package/dist/guest/runtime.js +1 -1
  151. package/dist/index.d.ts +12 -10
  152. package/dist/index.js +8 -6
  153. package/dist/keys/key-resolution.d.ts +5 -5
  154. package/dist/keys/key-resolution.js +23 -23
  155. package/dist/lab/adapter-extension.d.ts +7 -7
  156. package/dist/lab/adapter-extension.js +13 -36
  157. package/dist/lab/adapter-scorer-loader.d.ts +7 -7
  158. package/dist/lab/adapter-scorer-loader.js +32 -32
  159. package/dist/lab/composition-rules.js +42 -42
  160. package/dist/lab/config.js +65 -25
  161. package/dist/lab/deprecated-fields.d.ts +10 -0
  162. package/dist/lab/deprecated-fields.js +24 -0
  163. package/dist/lab/device-presets.d.ts +8 -8
  164. package/dist/lab/device-presets.js +11 -11
  165. package/dist/lab/discover.d.ts +13 -9
  166. package/dist/lab/discover.js +117 -57
  167. package/dist/lab/doctor.d.ts +10 -3
  168. package/dist/lab/doctor.js +47 -9
  169. package/dist/lab/init-templates.js +147 -147
  170. package/dist/lab/init.d.ts +1 -1
  171. package/dist/lab/init.js +41 -9
  172. package/dist/lab/keys.d.ts +2 -0
  173. package/dist/lab/keys.js +42 -8
  174. package/dist/lab/lab-deps.d.ts +7 -12
  175. package/dist/lab/parse/actors.js +9 -9
  176. package/dist/lab/parse/comms.js +5 -5
  177. package/dist/lab/parse/execution.js +13 -13
  178. package/dist/lab/parse/study-v3.d.ts +23 -0
  179. package/dist/lab/parse/study-v3.js +259 -0
  180. package/dist/lab/parse/subject-state.d.ts +7 -7
  181. package/dist/lab/parse/subject-state.js +16 -16
  182. package/dist/lab/parse/subject.js +28 -28
  183. package/dist/lab/parse/values.d.ts +1 -1
  184. package/dist/lab/parse/values.js +3 -3
  185. package/dist/lab/persona-resolve.d.ts +4 -4
  186. package/dist/lab/persona-resolve.js +4 -4
  187. package/dist/lab/plan-participants.d.ts +2 -2
  188. package/dist/lab/plan-types.d.ts +4 -4
  189. package/dist/lab/plan.d.ts +1 -7
  190. package/dist/lab/plan.js +10 -41
  191. package/dist/lab/preflight-probes.js +11 -11
  192. package/dist/lab/preflight-result.d.ts +2 -1
  193. package/dist/lab/preflight-result.js +5 -4
  194. package/dist/lab/preflight.d.ts +7 -5
  195. package/dist/lab/preflight.js +5 -5
  196. package/dist/lab/routing.d.ts +31 -25
  197. package/dist/lab/routing.js +60 -29
  198. package/dist/lab/run-lab-events.d.ts +0 -3
  199. package/dist/lab/run-lab-events.js +0 -6
  200. package/dist/lab/run-lab-homes.d.ts +22 -10
  201. package/dist/lab/run-lab-homes.js +5 -1
  202. package/dist/lab/run-lab-options.d.ts +1 -1
  203. package/dist/lab/run-lab-options.js +16 -13
  204. package/dist/lab/summary.d.ts +7 -6
  205. package/dist/lab/summary.js +10 -10
  206. package/dist/lab/tasks.d.ts +15 -15
  207. package/dist/lab/tasks.js +14 -14
  208. package/dist/lab/types.d.ts +101 -95
  209. package/dist/lab/types.js +2 -0
  210. package/dist/lab/validation.d.ts +13 -13
  211. package/dist/lab/validation.js +44 -42
  212. package/dist/lab/warnings.d.ts +10 -0
  213. package/dist/lab/warnings.js +61 -33
  214. package/dist/library-aliases.d.ts +56 -0
  215. package/dist/library-aliases.js +22 -0
  216. package/dist/observer/artifact.d.ts +1 -1
  217. package/dist/observer/artifact.js +6 -6
  218. package/dist/observer/data.d.ts +6 -6
  219. package/dist/observer/data.js +5 -4
  220. package/dist/observer/exposure.d.ts +1 -1
  221. package/dist/observer/exposure.js +11 -11
  222. package/dist/observer/http.js +1 -1
  223. package/dist/observer/library.d.ts +1 -1
  224. package/dist/observer/library.js +4 -2
  225. package/dist/observer/listen.js +5 -4
  226. package/dist/observer/render.d.ts +1 -1
  227. package/dist/observer/render.js +10 -5
  228. package/dist/observer/run-routes.d.ts +3 -3
  229. package/dist/observer/run-routes.js +1 -1
  230. package/dist/observer/serve.js +7 -3
  231. package/dist/observer/tunnel.js +1 -1
  232. package/dist/observer-app.html +4 -4
  233. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  234. package/dist/routes/computer-use/bundle-parts.js +15 -15
  235. package/dist/routes/computer-use/bundle.js +3 -3
  236. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
  237. package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
  238. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
  239. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
  240. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
  241. package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
  242. package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
  243. package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
  244. package/dist/routes/computer-use/external-comms.d.ts +1 -1
  245. package/dist/routes/computer-use/external-comms.js +1 -1
  246. package/dist/routes/computer-use/fanout-bundle.js +18 -18
  247. package/dist/routes/computer-use/fanout-records.js +10 -11
  248. package/dist/routes/computer-use/live-flush.d.ts +1 -1
  249. package/dist/routes/computer-use/live-flush.js +6 -6
  250. package/dist/routes/computer-use/live-phase.d.ts +4 -2
  251. package/dist/routes/computer-use/live-phase.js +6 -6
  252. package/dist/routes/computer-use/local-vm.js +1 -1
  253. package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
  254. package/dist/routes/computer-use/participant-desktop.js +4 -4
  255. package/dist/routes/computer-use/participant-execution.d.ts +4 -4
  256. package/dist/routes/computer-use/participant-execution.js +9 -9
  257. package/dist/routes/computer-use/participant-model.d.ts +6 -0
  258. package/dist/routes/computer-use/participant-model.js +31 -13
  259. package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
  260. package/dist/routes/computer-use/participant-prompt.js +6 -6
  261. package/dist/routes/computer-use/participant-runs.d.ts +7 -7
  262. package/dist/routes/computer-use/participant-runs.js +13 -13
  263. package/dist/routes/computer-use/plan.js +22 -22
  264. package/dist/routes/computer-use/preflight.js +21 -21
  265. package/dist/routes/computer-use/rerun-selection.js +1 -1
  266. package/dist/routes/computer-use/result.js +11 -11
  267. package/dist/routes/computer-use/route.d.ts +2 -1
  268. package/dist/routes/computer-use/route.js +15 -14
  269. package/dist/routes/computer-use/self-report.d.ts +7 -7
  270. package/dist/routes/computer-use/self-report.js +31 -31
  271. package/dist/routes/computer-use/setup.d.ts +1 -1
  272. package/dist/routes/computer-use/setup.js +17 -18
  273. package/dist/routes/computer-use/single-bundle.d.ts +7 -7
  274. package/dist/routes/computer-use/single-bundle.js +28 -30
  275. package/dist/routes/computer-use/subject-projection.d.ts +1 -1
  276. package/dist/routes/computer-use/subject-projection.js +6 -6
  277. package/dist/routes/computer-use/types.d.ts +40 -42
  278. package/dist/routes/computer-use/types.js +10 -10
  279. package/dist/routes/preview.d.ts +8 -2
  280. package/dist/routes/preview.js +8 -4
  281. package/dist/routes/scripted/bundle.d.ts +2 -2
  282. package/dist/routes/scripted/bundle.js +13 -12
  283. package/dist/routes/scripted/plan.d.ts +1 -1
  284. package/dist/routes/scripted/plan.js +9 -9
  285. package/dist/routes/scripted/result.js +5 -5
  286. package/dist/routes/scripted/route.js +5 -6
  287. package/dist/routes/scripted/scenario.js +2 -2
  288. package/dist/routes/scripted/setup.js +7 -7
  289. package/dist/routes/scripted/subject.js +1 -1
  290. package/dist/routes/scripted/surface-records.js +3 -3
  291. package/dist/routes/scripted/types.d.ts +3 -5
  292. package/dist/routes/scripted/types.js +1 -1
  293. package/dist/routes/shared-world/bundle-records.js +9 -8
  294. package/dist/routes/shared-world/bundle.d.ts +5 -5
  295. package/dist/routes/shared-world/bundle.js +40 -38
  296. package/dist/routes/shared-world/checkpoints.d.ts +1 -1
  297. package/dist/routes/shared-world/checkpoints.js +1 -1
  298. package/dist/routes/shared-world/comms.d.ts +5 -5
  299. package/dist/routes/shared-world/comms.js +14 -14
  300. package/dist/routes/shared-world/external-public.d.ts +4 -3
  301. package/dist/routes/shared-world/external-public.js +16 -12
  302. package/dist/routes/shared-world/handoff.d.ts +7 -6
  303. package/dist/routes/shared-world/handoff.js +65 -57
  304. package/dist/routes/shared-world/lobby-code.d.ts +2 -2
  305. package/dist/routes/shared-world/lobby-code.js +9 -9
  306. package/dist/routes/shared-world/participant-specs.d.ts +7 -6
  307. package/dist/routes/shared-world/participant-specs.js +31 -24
  308. package/dist/routes/shared-world/plan.js +7 -7
  309. package/dist/routes/shared-world/provenance.d.ts +2 -2
  310. package/dist/routes/shared-world/provenance.js +2 -2
  311. package/dist/routes/shared-world/provisioned.js +14 -13
  312. package/dist/routes/shared-world/result.js +20 -21
  313. package/dist/routes/shared-world/route.js +23 -22
  314. package/dist/routes/shared-world/setup.d.ts +3 -3
  315. package/dist/routes/shared-world/setup.js +4 -4
  316. package/dist/routes/shared-world/types.d.ts +30 -28
  317. package/dist/routes/shared-world/types.js +4 -4
  318. package/dist/routes/terminal/adapter.d.ts +3 -3
  319. package/dist/routes/terminal/adapter.js +5 -5
  320. package/dist/routes/terminal/bundle.d.ts +3 -3
  321. package/dist/routes/terminal/bundle.js +22 -21
  322. package/dist/routes/terminal/credentials.d.ts +4 -4
  323. package/dist/routes/terminal/credentials.js +7 -7
  324. package/dist/routes/terminal/dry-run.js +4 -4
  325. package/dist/routes/terminal/encoding.js +2 -2
  326. package/dist/routes/terminal/ledger.d.ts +3 -3
  327. package/dist/routes/terminal/ledger.js +14 -14
  328. package/dist/routes/terminal/live-finish.js +3 -3
  329. package/dist/routes/terminal/live-sandbox.js +12 -13
  330. package/dist/routes/terminal/persona.js +1 -1
  331. package/dist/routes/terminal/plan.js +11 -11
  332. package/dist/routes/terminal/recorder.js +2 -2
  333. package/dist/routes/terminal/result.js +8 -8
  334. package/dist/routes/terminal/route.js +6 -7
  335. package/dist/routes/terminal/sandbox.d.ts +1 -1
  336. package/dist/routes/terminal/sandbox.js +1 -1
  337. package/dist/routes/terminal/session.js +8 -7
  338. package/dist/routes/terminal/token-usage.d.ts +1 -1
  339. package/dist/routes/terminal/token-usage.js +7 -8
  340. package/dist/routes/terminal/trace.d.ts +2 -2
  341. package/dist/routes/terminal/trace.js +2 -2
  342. package/dist/routes/terminal/types.d.ts +26 -28
  343. package/dist/routes/terminal/types.js +3 -3
  344. package/dist/run/bundle-shape.js +3 -3
  345. package/dist/run/bundle.d.ts +46 -46
  346. package/dist/run/bundle.js +2 -1
  347. package/dist/run/cost-summary.js +3 -3
  348. package/dist/run/costs.js +7 -1
  349. package/dist/run/detail.d.ts +6 -6
  350. package/dist/run/detail.js +4 -4
  351. package/dist/run/dry-run-inputs.js +1 -1
  352. package/dist/run/dry-run.js +18 -18
  353. package/dist/run/judge.d.ts +19 -13
  354. package/dist/run/judge.js +18 -8
  355. package/dist/run/paths.d.ts +1 -1
  356. package/dist/run/paths.js +1 -1
  357. package/dist/run/pricing.d.ts +11 -6
  358. package/dist/run/pricing.js +20 -13
  359. package/dist/run/projection.d.ts +14 -14
  360. package/dist/run/projection.js +15 -15
  361. package/dist/run/reclaim.js +2 -2
  362. package/dist/run/results.d.ts +5 -5
  363. package/dist/run/run-index.d.ts +8 -6
  364. package/dist/run/run-index.js +15 -16
  365. package/dist/run/run-not-found.d.ts +5 -0
  366. package/dist/run/run-not-found.js +15 -0
  367. package/dist/run/run.d.ts +5 -4
  368. package/dist/run/run.js +1 -1
  369. package/dist/run/sandbox-receipts.d.ts +2 -2
  370. package/dist/run/sandbox-receipts.js +3 -3
  371. package/dist/run/shared-world-evidence.d.ts +36 -35
  372. package/dist/run/shared-world-evidence.js +4 -4
  373. package/dist/run/shared-world-shape.d.ts +1 -1
  374. package/dist/run/shared-world-shape.js +6 -6
  375. package/dist/run/stats.d.ts +12 -6
  376. package/dist/run/stats.js +116 -58
  377. package/dist/run/status.d.ts +8 -29
  378. package/dist/run/status.js +5 -27
  379. package/dist/run/stored-runs.js +2 -1
  380. package/dist/run/stream-shape.js +1 -1
  381. package/dist/run/streams.d.ts +6 -6
  382. package/dist/run/study-provenance.d.ts +47 -0
  383. package/dist/run/study-provenance.js +63 -0
  384. package/dist/run/study-result.d.ts +16 -0
  385. package/dist/run/study-result.js +9 -0
  386. package/dist/run/text.d.ts +2 -0
  387. package/dist/run/text.js +4 -0
  388. package/dist/run-lab.d.ts +7 -7
  389. package/dist/run-lab.js +1 -3
  390. package/dist/study/convert.d.ts +33 -0
  391. package/dist/study/convert.js +432 -0
  392. package/dist/study/field-paths.d.ts +12 -0
  393. package/dist/study/field-paths.js +126 -0
  394. package/dist/study/files.d.ts +26 -0
  395. package/dist/study/files.js +43 -0
  396. package/dist/study/migrate.d.ts +48 -0
  397. package/dist/study/migrate.js +408 -0
  398. package/dist/study/owned-files.d.ts +38 -0
  399. package/dist/study/owned-files.js +182 -0
  400. package/dist/subject/clone.d.ts +1 -1
  401. package/dist/subject/desktop-cli.d.ts +1 -1
  402. package/dist/subject/desktop-cli.js +2 -2
  403. package/dist/subject/local-tree-archive.js +1 -1
  404. package/dist/subject/local-tree.d.ts +1 -1
  405. package/dist/subject/node-bootstrap.js +1 -1
  406. package/dist/subject/runtime.js +8 -9
  407. package/dist/subject/serve.d.ts +1 -1
  408. package/dist/subject/serve.js +3 -3
  409. package/dist/subject/state.d.ts +1 -1
  410. package/dist/subject/steps.d.ts +5 -5
  411. package/dist/subject/steps.js +4 -4
  412. package/dist/substrates/command-failure.d.ts +3 -3
  413. package/dist/substrates/command-failure.js +3 -3
  414. package/dist/substrates/detached.d.ts +6 -6
  415. package/dist/substrates/detached.js +7 -7
  416. package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
  417. package/dist/substrates/e2b/cdp-probe.js +14 -17
  418. package/dist/substrates/e2b/desktop-browser.d.ts +2 -2
  419. package/dist/substrates/e2b/desktop-browser.js +8 -8
  420. package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
  421. package/dist/substrates/e2b/desktop-cdp.js +8 -8
  422. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  423. package/dist/substrates/e2b/desktop-executor.js +1 -1
  424. package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
  425. package/dist/substrates/e2b/desktop-geometry.js +7 -7
  426. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  427. package/dist/substrates/e2b/desktop-media.js +1 -1
  428. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  429. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  430. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  431. package/dist/substrates/e2b/sandbox.js +1 -1
  432. package/dist/substrates/e2b/sdk.d.ts +11 -11
  433. package/dist/substrates/e2b/sdk.js +6 -6
  434. package/dist/tui/actions.d.ts +1 -1
  435. package/dist/tui/actions.js +13 -13
  436. package/dist/tui/contract.d.ts +16 -16
  437. package/dist/tui/contract.js +10 -10
  438. package/dist/tui/launch.d.ts +4 -4
  439. package/dist/tui/launch.js +18 -19
  440. package/dist/tui/project.js +5 -5
  441. package/dist/tui-app.js +82 -82
  442. package/dist/verify/actor.d.ts +8 -8
  443. package/dist/verify/actor.js +36 -36
  444. package/dist/verify/artifacts.d.ts +2 -2
  445. package/dist/verify/artifacts.js +3 -3
  446. package/dist/verify/context-growth.d.ts +9 -0
  447. package/dist/verify/context-growth.js +62 -0
  448. package/dist/verify/costs.d.ts +6 -6
  449. package/dist/verify/costs.js +8 -8
  450. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  451. package/dist/verify/shared-world-concurrent.js +79 -76
  452. package/dist/verify/shared-world.d.ts +2 -2
  453. package/dist/verify/shared-world.js +16 -16
  454. package/dist/verify/subject.d.ts +4 -4
  455. package/dist/verify/subject.js +18 -18
  456. package/dist/verify/verify.js +92 -43
  457. package/docs/README.md +25 -32
  458. package/docs/architecture/actor-contract.md +56 -87
  459. package/docs/architecture/desktop-sessions.md +7 -7
  460. package/docs/architecture/external-public-shared-world.md +61 -59
  461. package/docs/architecture/github-feedback-loop.md +1 -4
  462. package/docs/architecture/guest-desktop.md +2 -2
  463. package/docs/architecture/observer.md +34 -34
  464. package/docs/architecture/restricted-codex-analysis.md +34 -28
  465. package/docs/architecture/serve.md +34 -37
  466. package/docs/architecture/state-driven-executor.md +55 -58
  467. package/docs/architecture/task-protocol-support.md +5 -5
  468. package/docs/architecture/terminal-product-route.md +67 -107
  469. package/docs/contracts/README.md +24 -0
  470. package/docs/contracts/adapter-admission.md +3 -3
  471. package/docs/contracts/adapter-fixtures.md +2 -5
  472. package/docs/contracts/core.md +1 -3
  473. package/docs/contracts/errors.md +62 -0
  474. package/docs/contracts/feedback.md +8 -9
  475. package/docs/contracts/policy.md +7 -12
  476. package/docs/contracts/run-bundle.md +45 -44
  477. package/docs/contracts/schemas.md +421 -362
  478. package/docs/contracts/study-analysis.md +3 -3
  479. package/docs/contracts/study-costs.md +11 -7
  480. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  481. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  482. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  483. package/docs/principles/actor-fidelity.md +4 -4
  484. package/docs/principles/engineering.md +3 -3
  485. package/docs/principles/invariants-and-defaults.md +38 -38
  486. package/docs/principles/self-driving-harness.md +1 -5
  487. package/docs/principles/three-roles.md +1 -1
  488. package/docs/product/automatic-analysis.md +7 -7
  489. package/examples/participant/README.md +5 -5
  490. package/examples/participant/run.mjs +11 -10
  491. package/examples/scorer/README.md +3 -3
  492. package/examples/scorer/run.mjs +11 -12
  493. package/package.json +16 -17
  494. package/skills/humanish/SKILL.md +60 -58
  495. package/skills/humanish/agents/openai.yaml +1 -1
  496. package/AGENTS.md +0 -99
  497. package/CONTRIBUTING.md +0 -148
  498. package/dist/actors/codex/qualified-versions.d.ts +0 -72
  499. package/dist/actors/codex/qualified-versions.js +0 -132
  500. package/dist/cli/commands/lab.d.ts +0 -3
  501. package/dist/cli/commands/lab.js +0 -199
  502. package/dist/cli/renamed-options.d.ts +0 -11
  503. package/dist/cli/renamed-options.js +0 -18
  504. package/dist/observer/static.d.ts +0 -39
  505. package/dist/observer/static.js +0 -369
  506. package/docs/architecture/comms-inbox.md +0 -122
  507. package/docs/architecture/desktop-recording.md +0 -80
  508. package/docs/architecture/local-browser-runtime.md +0 -178
  509. package/docs/architecture/observer-review.md +0 -144
  510. package/docs/architecture/participant-media.md +0 -90
  511. package/docs/architecture/project-layout.md +0 -62
  512. package/docs/architecture/real-email-receiving.md +0 -136
  513. package/docs/assets/humanish-drawdb-hero.png +0 -0
  514. package/docs/assets/humanish-observer-hero.png +0 -0
  515. package/docs/goals/current.md +0 -207
  516. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  517. package/docs/product/open-source-install-experience.md +0 -240
  518. package/docs/ramp/README.md +0 -295
  519. package/docs/release/open-source-readiness.md +0 -222
  520. package/docs/release/public-readiness-standard.md +0 -210
  521. package/docs/roadmap/world-class-open-source-v0.md +0 -311
@@ -41,7 +41,7 @@ function fanoutParticipantView(args, spec, index) {
41
41
  : (outcome?.skippedReason ??
42
42
  session?.reason ??
43
43
  outcome?.sessionError ??
44
- "Contract bundle only: dry-run produced the evidence shape without launching a desktop or spending provider tokens.");
44
+ "Dry run: the evidence shape was written without launching a desktop or spending provider tokens.");
45
45
  const traceScreenshotMode = session?.trace.redaction.screenshots;
46
46
  const screenshotMode = traceScreenshotMode === "raw" || traceScreenshotMode === "blurred"
47
47
  ? traceScreenshotMode
@@ -80,13 +80,12 @@ function fanoutParticipantRecord(args, spec, index, view) {
80
80
  ? `Participant ${spec.planned.id} ${outcome.skippedReason}.`
81
81
  : outcome?.sessionError !== undefined
82
82
  ? `Participant ${spec.planned.id} failed before a terminal session verdict: ${outcome.sessionError}`
83
- : `Contract participant ${spec.planned.id} (${spec.persona.id}/${spec.planned.device.name}) for ${args.descriptor.id} against ${publicTargetUrl}.`,
83
+ : `Participant ${spec.planned.id} (${spec.persona.id}/${spec.planned.device.name}) for ${args.descriptor.id} against ${publicTargetUrl}; no session ran.`,
84
84
  startedAt: args.run.createdAt,
85
85
  updatedAt: args.run.createdAt,
86
86
  });
87
87
  }
88
88
  function fanoutParticipantStream(args, spec, view) {
89
- const { plan } = args;
90
89
  const { outcome, publicTargetUrl, session, desktopGeometry, screenshots } = view;
91
90
  const { lastScreenshot, status, reason, screenshotMode } = view;
92
91
  const judged = outcome === undefined ? undefined : judgedStatus(participantFactsOf(outcome));
@@ -104,7 +103,7 @@ function fanoutParticipantStream(args, spec, view) {
104
103
  ? {}
105
104
  : { caseGroup: spec.planned.labels.caseGroup }),
106
105
  kind: "browser",
107
- label: `CUA participant ${spec.planned.id}: ${plan.labId}`,
106
+ label: `${spec.planned.id} · browser`,
108
107
  status,
109
108
  ...(judged === undefined ? {} : { judgedStatus: judged }),
110
109
  transport: "snapshot",
@@ -113,9 +112,9 @@ function fanoutParticipantStream(args, spec, view) {
113
112
  ? {
114
113
  kind: "screenshot",
115
114
  url: lastScreenshot,
116
- title: `CUA desktop ${spec.planned.id} (${screenshotMode})`,
115
+ title: `Desktop (${screenshotMode})`,
117
116
  }
118
- : { kind: "placeholder", title: `CUA desktop ${spec.planned.id}` },
117
+ : { kind: "placeholder", title: "Desktop" },
119
118
  ...(desktopGeometry.viewport === undefined
120
119
  ? {}
121
120
  : {
@@ -180,7 +179,7 @@ function fanoutSubjectEvents(ctx, spec, view) {
180
179
  const { publicTargetUrl, subject, session } = view;
181
180
  const events = [];
182
181
  const record = (event) => events.push(participantEvent(spec, event));
183
- // Per-participant subject provenance (invariant 5).
182
+ // Per-participant subject provenance.
184
183
  if (args.plan.runner.subject.kind === "clone" && args.publicRepo) {
185
184
  record({
186
185
  id: nextEventId(`subject-${spec.planned.id}`),
@@ -188,7 +187,7 @@ function fanoutSubjectEvents(ctx, spec, view) {
188
187
  level: "info",
189
188
  type: "cua-lab.subject.provenance",
190
189
  message: `Participant ${spec.planned.id}: ${args.dryRun
191
- ? `subject declared: clone of ${args.publicRepo}, served at ${publicTargetUrl} in-sandbox (dry-run contract; nothing cloned)`
190
+ ? `subject declared: clone of ${args.publicRepo}, served at ${publicTargetUrl} in-sandbox (dry run; nothing cloned)`
192
191
  : subject.commit
193
192
  ? session
194
193
  ? `subject cloned from ${args.publicRepo}@${subject.commit} and served at ${publicTargetUrl} in-sandbox`
@@ -203,7 +202,7 @@ function fanoutSubjectEvents(ctx, spec, view) {
203
202
  level: "info",
204
203
  type: "cua-lab.subject.provenance",
205
204
  message: `Participant ${spec.planned.id}: ${args.dryRun
206
- ? `subject declared: local working tree, to be packed and served at ${publicTargetUrl} in-sandbox (dry-run contract; nothing packed)`
205
+ ? `subject declared: local working tree, to be packed and served at ${publicTargetUrl} in-sandbox (dry run; nothing packed)`
207
206
  : subject.archiveSha256
208
207
  ? session
209
208
  ? `subject packed (archiveSha256 ${subject.archiveSha256}${subject.dirty === true ? ", dirty working tree" : subject.dirty === false ? ", clean working tree" : ""}) and served at ${publicTargetUrl} in-sandbox`
@@ -270,7 +269,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
270
269
  at: args.run.createdAt,
271
270
  level: "info",
272
271
  type: "cua-lab.contract.ready",
273
- message: `Participant ${spec.planned.id}: dry-run contract participant ready; switch scenario.mode to live for a real desktop session.`,
272
+ message: `Participant ${spec.planned.id}: dry-run participant ready; switch scenario.mode to live for a real desktop session.`,
274
273
  });
275
274
  }
276
275
  for (const warning of desktopGeometry.warnings ?? []) {
@@ -282,7 +281,7 @@ function fanoutOutcomeEvents(ctx, spec, view) {
282
281
  message: warning,
283
282
  });
284
283
  }
285
- // Persisted per-participant phase trail (real boot timing): one RunEvent per COMPLETED phase
284
+ // Persisted per-participant phase trail (real boot timing): one RunEvent per completed phase
286
285
  // boundary this participant recorded (started events never persist here; they carry no durationMs).
287
286
  for (const phase of outcome?.phaseRecords ?? []) {
288
287
  record({
@@ -12,7 +12,7 @@ export interface LiveTraceFlush {
12
12
  stop: () => Promise<void>;
13
13
  }
14
14
  /**
15
- * Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
15
+ * Incremental live flush: as each participant's loop reports its recorded-so-far items,
16
16
  * rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
17
17
  * Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
18
18
  * write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
@@ -1,7 +1,7 @@
1
1
  import { attachObserverRuntimeStreamUrls } from "../../observer/render.js";
2
2
  import {} from "../../observer/run-routes.js";
3
3
  /**
4
- * Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
4
+ * Incremental live flush: as each participant's loop reports its recorded-so-far items,
5
5
  * rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
6
6
  * Observer's 5s poll sees the timeline grow. Throttled (one write per interval, trailing
7
7
  * write guaranteed). `write` is the run's `writeSnapshot`, which serializes writes and refuses
@@ -42,9 +42,9 @@ export function startLiveTraceFlush(args) {
42
42
  liveActor: {
43
43
  schema: "humanish.live-actor.v1",
44
44
  updatedAt,
45
- // WHO this participant is, carried while the run is live. Without it a
46
- // surface watching a live run can only name the participant id, and "CUA browser — observer-live-
47
- // check" is the harness talking about itself where the participant should be.
45
+ // Who this participant is, carried while the run is live. Without it a
46
+ // surface watching a live run can only name the participant id and the stream
47
+ // label (`<participant id> · browser`), which describe the harness, not the participant.
48
48
  ...(personaByStream.get(stream.id) === undefined
49
49
  ? {}
50
50
  : { persona: { id: personaByStream.get(stream.id) } }),
@@ -125,8 +125,8 @@ export function trackRuntimeStreams(onStream) {
125
125
  await onStream?.(event);
126
126
  if (event.type === "ready")
127
127
  urls.push({ streamId: event.streamId, url: event.url });
128
- // Mark, never remove: the tile needs to KNOW the live view ended (and say so) rather than
129
- // have the stream silently vanish from the overlay (#357).
128
+ // Mark, never remove: the tile needs to know the live view ended (and say so) rather than
129
+ // have the stream silently vanish from the overlay.
130
130
  else
131
131
  for (const entry of urls)
132
132
  if (entry.streamId === event.streamId)
@@ -10,10 +10,12 @@ export declare function runLabParticipants(setup: CuaRunSetup, participants: Cua
10
10
  result: {
11
11
  automaticAnalysis?: import("../../analysis/job.js").AutomaticAnalysisOutcome;
12
12
  automaticAnalysisTrigger?: "default" | "explicit";
13
- schema: typeof import("./types.js").CUA_ACTOR_LAB_SCHEMA;
13
+ schema: typeof import("../../run/study-result.js").STUDY_RESULT_SCHEMA;
14
+ route: "computer-use";
15
+ studyId: string;
16
+ labId: string;
14
17
  ok: boolean;
15
18
  cwd: string;
16
- labId: string;
17
19
  actor: string;
18
20
  appUrl: string;
19
21
  dryRun: boolean;
@@ -20,10 +20,10 @@ export async function runLabParticipants(setup, participants) {
20
20
  const inProcess = plan.runner.desktop === "in-process";
21
21
  const subjectEnvNames = [...participantSubjectEnv(plan.runner.subject)];
22
22
  const { runId, paths: runPaths } = run;
23
- // A live run writes what it is doing AS IT DOES IT, whether or not anyone is currently watching.
24
- // This used to be gated on `options.onObserverReady` — the interactive Observer callback — so a
25
- // run launched by an agent (`lab run --json`), detached, or from the terminal surface recorded
26
- // nothing at all until it completed, and anything asking "what is this participant doing right
23
+ // A live run writes what it is doing as it does it, whether or not anyone is currently watching.
24
+ // This is not gated on `options.onObserverReady` (the interactive Observer callback): gated, a
25
+ // run launched by an agent (`lab run --json`), detached, or from the terminal surface records
26
+ // nothing at all until it completes, and anything asking "what is this participant doing right
27
27
  // now" got silence for the whole run. Who reads the evidence is not the run's business; the
28
28
  // callback below stays conditional, the writing does not.
29
29
  if (!dryRun) {
@@ -47,7 +47,7 @@ export async function runLabParticipants(setup, participants) {
47
47
  streams.showIn(liveObserver);
48
48
  if (input.onObserverReady)
49
49
  await input.onObserverReady(liveObserver);
50
- // Incremental live flush (#441): as each participant's loop reports its recorded-so-far items,
50
+ // Incremental live flush: as each participant's loop reports its recorded-so-far items,
51
51
  // rewrite the in-progress bundle with per-stream `liveActor` partials so the attached
52
52
  // Observer's 5s poll sees the timeline grow. The run refuses any snapshot once the final
53
53
  // write began; the route stops the flush timer on every exit below.
@@ -91,7 +91,7 @@ export async function runLabParticipants(setup, participants) {
91
91
  return {
92
92
  ok: false,
93
93
  result: {
94
- ...fail("HUMANISH_CUA_LAB_SUBJECT_INVALID", "Real email setup failed before desktop allocation. Run humanish comms check --online and humanish comms recover to inspect authentication and pending cleanup.", descriptor.id),
94
+ ...fail("HUMANISH_COMPUTER_USE_SUBJECT_INVALID", "Real email setup failed before desktop allocation. Run humanish comms check --online and humanish comms recover to inspect authentication and pending cleanup.", descriptor.id),
95
95
  runId,
96
96
  },
97
97
  };
@@ -26,7 +26,7 @@ function guestAssets(options, account, needsMedia) {
26
26
  if (account) {
27
27
  const readiness = await checkRestrictedCodexAnalysisReadiness({ timeoutMs: 5000 });
28
28
  if (!readiness.ready)
29
- throw new Error(`Codex account is not ready (${readiness.errorCode}). Run humanish doctor --lab <lab> before starting a local study.`);
29
+ throw new Error(`Codex account is not ready (${readiness.errorCode}). Run humanish doctor --study <study> before starting a local study.`);
30
30
  }
31
31
  return (options.assets ??
32
32
  (await prepareLocalRuntime({
@@ -38,11 +38,11 @@ export interface ParticipantDesktop {
38
38
  }
39
39
  /** Builds one participant's desktop. The factory must not acquire anything; prepare does. */
40
40
  export type ParticipantDesktopFactory = (run: DesktopParticipantRun, warnings: string[], artifactRoot: PreparedOutputRoot) => ParticipantDesktop;
41
- /** The participant's addressed comms recipient, when one exists — the gate AND the address source for the
42
- * inbox instruction (#351). A participant told to check an inbox it can never receive into would stall,
41
+ /** The participant's addressed comms recipient, when one exists: the gate and the address source for the
42
+ * inbox instruction. A participant told to check an inbox it can never receive into would stall,
43
43
  * so no addressed recipient means no instruction. */
44
44
  export declare function inboxRecipientFor(commsEmail: LabCommsEmail, participantId: string): LabCommsRecipient | undefined;
45
- /** True when a participant has a declared comms recipient WITH an address, so the drain can actually match the
45
+ /** True when a participant has a declared comms recipient with an address, so the drain can actually match the
46
46
  * mail the persona will be told to read. Gates the inbox instruction to participants that can receive
47
- * mail — a participant told to check an inbox it can never receive into would just stall. */
47
+ * mail; a participant told to check an inbox it can never receive into would just stall. */
48
48
  export declare function participantHasInboxRecipient(commsEmail: LabCommsEmail, participantId: string): boolean;
@@ -1,13 +1,13 @@
1
1
  import { recipientParticipantId } from "../../lab/parse/comms.js";
2
- /** The participant's addressed comms recipient, when one exists — the gate AND the address source for the
3
- * inbox instruction (#351). A participant told to check an inbox it can never receive into would stall,
2
+ /** The participant's addressed comms recipient, when one exists: the gate and the address source for the
3
+ * inbox instruction. A participant told to check an inbox it can never receive into would stall,
4
4
  * so no addressed recipient means no instruction. */
5
5
  export function inboxRecipientFor(commsEmail, participantId) {
6
6
  return (commsEmail.recipients ?? []).find((recipient) => recipientParticipantId(recipient) === participantId && recipient.address !== undefined);
7
7
  }
8
- /** True when a participant has a declared comms recipient WITH an address, so the drain can actually match the
8
+ /** True when a participant has a declared comms recipient with an address, so the drain can actually match the
9
9
  * mail the persona will be told to read. Gates the inbox instruction to participants that can receive
10
- * mail — a participant told to check an inbox it can never receive into would just stall. */
10
+ * mail; a participant told to check an inbox it can never receive into would just stall. */
11
11
  export function participantHasInboxRecipient(commsEmail, participantId) {
12
12
  return inboxRecipientFor(commsEmail, participantId) !== undefined;
13
13
  }
@@ -11,12 +11,12 @@ export declare function makeParticipantWriteScreenshot(artifactRoot: PreparedOut
11
11
  export declare function runCuaParticipant(spec: DesktopParticipantRun, deps: CuaParticipantDeps): Promise<ParticipantRunOutcome>;
12
12
  /**
13
13
  * Run N>1 E2B participants with bounded concurrency, a pipeline gate (the first provisions
14
- * before the rest start), and session fail-fast on HARNESS errors only (queued participants
14
+ * before the rest start), and session fail-fast on harness errors only (queued participants
15
15
  * become `blocked` with a pinned reason + a fail-fast event; mission verdicts never trip it).
16
- * Each participant tears down ITS OWN sandbox by id; nothing here ever enumerates.
16
+ * Each participant tears down its own sandbox by id; nothing here ever enumerates.
17
17
  *
18
- * Exported for the #342 total-runner tests: the injectable runner lets a test make one participant
19
- * THROW (the exact class the guard exists for) without a live sandbox. Production always uses
18
+ * Exported for the total-runner tests: the injectable runner lets a test make one participant
19
+ * throw (the exact class the guard exists for) without a live sandbox. Production always uses
20
20
  * the default.
21
21
  */
22
22
  export declare function runCuaParticipants(runs: DesktopParticipantRun[], deps: Omit<CuaParticipantDeps, "signalProvisioned">, concurrency: number, runParticipant?: typeof runCuaParticipant): Promise<{
@@ -132,12 +132,12 @@ export async function runCuaParticipant(spec, deps) {
132
132
  }
133
133
  /**
134
134
  * Run N>1 E2B participants with bounded concurrency, a pipeline gate (the first provisions
135
- * before the rest start), and session fail-fast on HARNESS errors only (queued participants
135
+ * before the rest start), and session fail-fast on harness errors only (queued participants
136
136
  * become `blocked` with a pinned reason + a fail-fast event; mission verdicts never trip it).
137
- * Each participant tears down ITS OWN sandbox by id; nothing here ever enumerates.
137
+ * Each participant tears down its own sandbox by id; nothing here ever enumerates.
138
138
  *
139
- * Exported for the #342 total-runner tests: the injectable runner lets a test make one participant
140
- * THROW (the exact class the guard exists for) without a live sandbox. Production always uses
139
+ * Exported for the total-runner tests: the injectable runner lets a test make one participant
140
+ * throw (the exact class the guard exists for) without a live sandbox. Production always uses
141
141
  * the default.
142
142
  */
143
143
  export async function runCuaParticipants(runs, deps, concurrency, runParticipant = runCuaParticipant) {
@@ -164,10 +164,10 @@ export async function runCuaParticipants(runs, deps, concurrency, runParticipant
164
164
  if (failFast.tripped) {
165
165
  return skippedOutcome(spec, `skipped: ${failFast.reason}`);
166
166
  }
167
- // The participant runner is TOTAL (#342): every exit path returns a recorded outcome. Without this
167
+ // The participant runner is total: every exit path returns a recorded outcome. Without this
168
168
  // guard, one participant's late throw (e.g. its trace write hitting ENOSPC after its own sandbox was
169
169
  // already torn down) rejected the whole map while sibling workers kept launching sandboxes
170
- // nobody would ever record — the run spent money and then reported nothing.
170
+ // nobody would ever record, so the run spent money and then reported nothing.
171
171
  let outcome;
172
172
  try {
173
173
  outcome = await runParticipant(spec, {
@@ -187,7 +187,7 @@ export async function runCuaParticipants(runs, deps, concurrency, runParticipant
187
187
  });
188
188
  }
189
189
  catch (error) {
190
- // The first participant may have thrown before signaling the provisioning gate — release the followers as
190
+ // The first participant may have thrown before signaling the provisioning gate; release the followers as
191
191
  // blocked rather than leaving them awaiting a gate that will never settle.
192
192
  if (index === 0)
193
193
  rejectGate?.();
@@ -247,7 +247,7 @@ export function toParticipantResult(spec, outcome, subject, dryRun) {
247
247
  ok: false,
248
248
  diagnostics: cuaParticipantDiagnostics({ dryRun, skipped: true }),
249
249
  skippedReason: outcome.skippedReason,
250
- error: { code: "HUMANISH_CUA_LAB_FAILED", message: outcome.skippedReason },
250
+ error: { code: "HUMANISH_COMPUTER_USE_FAILED", message: outcome.skippedReason },
251
251
  };
252
252
  }
253
253
  const session = outcome.session;
@@ -299,7 +299,7 @@ export function toParticipantResult(spec, outcome, subject, dryRun) {
299
299
  ? {}
300
300
  : {
301
301
  error: {
302
- code: outcome.failureCode ?? "HUMANISH_CUA_LAB_FAILED",
302
+ code: outcome.failureCode ?? "HUMANISH_COMPUTER_USE_FAILED",
303
303
  message: outcome.sessionError ??
304
304
  (outcome.noEngagement
305
305
  ? "Actor took no actions and produced no message (likely a blank/still-loading screen); not a credible goal_satisfied."
@@ -1,4 +1,5 @@
1
1
  import type { CuaExecutor, CuaLoopResult, CuaProvider } from "../../actors/computer-use/loop.js";
2
+ import type { ActorConversation } from "../../actors/contract.js";
2
3
  import type { CuaActorSessionOptions } from "../../actors/computer-use/actor.js";
3
4
  import { startClaudeSession } from "../../actors/local-agent/claude-session.js";
4
5
  import { createRestrictedCodexParticipant, type ParticipantProviderCloseResult } from "../../actors/codex/restricted-participant.js";
@@ -29,6 +30,11 @@ export declare function closeParticipantModel(model: ParticipantModel, warnings:
29
30
  }>;
30
31
  /** Prices the finished session's tokens onto its trace, writes the trace, and warns on raw screenshots. */
31
32
  export declare function recordParticipantTrace(spec: DesktopParticipantRun, deps: ParticipantModelDeps, session: CuaLoopResult, warnings: string[]): Promise<void>;
33
+ /**
34
+ * The run warning for a participant whose provider kept no conversation server-side, so humanish
35
+ * carried it on every request. It says why, and how many early turns became a text summary.
36
+ */
37
+ export declare function explicitContextWarning(conversation: ActorConversation): string;
32
38
  /** The checks that keep a goal_satisfied session from counting as a pass, with their warnings. */
33
39
  export declare function judgeParticipantSession(session: CuaLoopResult | undefined, deps: ParticipantModelDeps, warnings: string[]): {
34
40
  noEngagement: boolean;
@@ -49,10 +49,10 @@ export async function startParticipantModel(spec, deps, executor) {
49
49
  return { provider: codexParticipant.provider, codexParticipant };
50
50
  }
51
51
  if (localAgent === "claude") {
52
- // One session for the whole run, like the codex thread above (#520). The one-shot
52
+ // One session for the whole run, like the codex thread above. The one-shot
53
53
  // provider (createLocalAgentProvider) spawned `claude -p` per turn, and every turn
54
54
  // started with no memory of the last. HUMANISH_LOCAL_AGENT_ONE_SHOT=1 keeps that path
55
- // reachable as a MEASUREMENT switch: MemTrapBench (2026-08) reports memory frameworks
55
+ // reachable as a measurement switch: MemTrapBench (2026-08) reports memory frameworks
56
56
  // degrading agent performance by 10-40% on some tasks, so "remembers" has to be measured
57
57
  // against "does not" on the same lab, not assumed. The trace records which one ran.
58
58
  const oneShot = env.HUMANISH_LOCAL_AGENT_ONE_SHOT !== undefined &&
@@ -82,7 +82,7 @@ export async function startParticipantModel(spec, deps, executor) {
82
82
  /** The options the participant's session runs with: prompt, model settings, spend caps and callbacks. */
83
83
  export function participantSessionOptions(spec, deps, ready, provider, writeScreenshot) {
84
84
  const { executor, inbox } = ready;
85
- // The FAIL-CLOSED spend cap (execution.caps.maxUsd) is wired into the loop as maxUsd + an
85
+ // The fail-closed spend cap (execution.caps.maxUsd) is wired into the loop as maxUsd + an
86
86
  // injected pure per-turn estimator keyed on the resolved model. Preflight already refused a
87
87
  // cap on an unpriced model, so the estimate is measurable whenever a cap is in force. The
88
88
  // model id here matches provider.version (openai-responses-cu resolves the default when unset).
@@ -95,7 +95,7 @@ export function participantSessionOptions(spec, deps, ready, provider, writeScre
95
95
  persona: spec.persona,
96
96
  timeoutMs: deps.timeoutMs,
97
97
  // The brain is either a keyed API client or a CLI the operator is already signed in to.
98
- // Everything below this line — loop, executor, trace, affordances — is identical either
98
+ // Everything below this line (loop, executor, trace, affordances) is identical either
99
99
  // way, which is what makes a local-agent run comparable to an API one.
100
100
  ...(provider === undefined ? {} : { provider: provider }),
101
101
  openai: {
@@ -129,8 +129,8 @@ export function participantSessionOptions(spec, deps, ready, provider, writeScre
129
129
  : { stopWhen: spec.planned.limits.stopWhen }),
130
130
  ...(spec.planned.limits.dwell === undefined ? {} : { dwell: spec.planned.limits.dwell }),
131
131
  ...(spec.planned.tasks === undefined ? {} : { tasks: spec.planned.tasks }),
132
- // The STUDY budget (#299): this participant notes its own running estimate on the shared
133
- // ledger and stops when the RUN total crosses the cap — independent of the per-participant
132
+ // The study budget: this participant notes its own running estimate on the shared
133
+ // ledger and stops when the run total crosses the cap, independent of the per-participant
134
134
  // maxUsd above.
135
135
  ...(deps.runBudget === undefined
136
136
  ? {}
@@ -149,8 +149,8 @@ export function participantSessionOptions(spec, deps, ready, provider, writeScre
149
149
  ...(deps.onTrace === undefined
150
150
  ? {}
151
151
  : {
152
- // Forwards the RUNNING usage as well: the participant runner is where both are known, and usage
153
- // without it never reaches the flush — which is how the live cost stayed unknown.
152
+ // Forwards the running usage as well: the participant runner is where both are known, and usage
153
+ // without it never reaches the flush, which is how the live cost stayed unknown.
154
154
  onTrace: (items, usage, metadata) => deps.onTrace?.(spec.planned.id, items, usage, metadata),
155
155
  }),
156
156
  };
@@ -207,27 +207,45 @@ export async function closeParticipantModel(model, warnings) {
207
207
  }
208
208
  /** Prices the finished session's tokens onto its trace, writes the trace, and warns on raw screenshots. */
209
209
  export async function recordParticipantTrace(spec, deps, session, warnings) {
210
- // Per-participant model-token cost ESTIMATE, attached to the trace before it is persisted (the model
211
- // id is authoritative here — provider.version). Kept at the lab boundary so the pure loop
210
+ // Per-participant model-token cost estimate, attached to the trace before it is persisted (the model
211
+ // id is authoritative here: provider.version). Kept at the lab boundary so the pure loop
212
212
  // never depends on the operator rate table. estimateActorCost declares absent (null) for an
213
213
  // unknown rate / missing usage rather than guessing.
214
214
  session.trace.estimatedCost = estimateActorCostForExecution(session.trace.tokenUsage, session.trace.ids.model, session.trace.executionProfile);
215
215
  await writeContainedOutputFile(deps.artifactRoot, spec.traceArtifactPath, `${JSON.stringify(session.trace, null, 2)}\n`, "utf8");
216
+ const conversation = session.trace.conversation;
217
+ if (conversation?.mode === "explicit_context")
218
+ warnings.push(explicitContextWarning(conversation));
216
219
  if (session.trace.redaction.screenshots === "raw") {
217
- warnings.push("Screenshots are full-fidelity (raw) for local use — the bundle stays in gitignored .humanish and nothing scans these pixels; review them before sharing anywhere. Set policies.redactScreenshots: true to blur a share-as-is bundle.");
220
+ warnings.push("Screenshots are unblurred for local use: the bundle stays in the gitignored .humanish/ folder and nothing scans these pixels, so review them before sharing. Set policies.redactScreenshots: true to blur screenshots in a bundle you plan to share.");
218
221
  }
219
222
  }
223
+ /**
224
+ * The run warning for a participant whose provider kept no conversation server-side, so humanish
225
+ * carried it on every request. It says why, and how many early turns became a text summary.
226
+ */
227
+ export function explicitContextWarning(conversation) {
228
+ const why = conversation.explicitReason === "zdr_rejection"
229
+ ? `The OpenAI organization rejected server-side conversation state (zero data retention)${conversation.switchedAtRequest === undefined
230
+ ? ""
231
+ : ` on request ${conversation.switchedAtRequest}`}`
232
+ : "zeroDataRetention is set";
233
+ const summarized = conversation.summarizedTurns === 0
234
+ ? ""
235
+ : ` To stay within its token budget it summarized the ${conversation.summarizedTurns} oldest turns as text and dropped their screenshots.`;
236
+ return `${why}, so humanish carried this participant's conversation itself (explicit_context).${summarized} The trace's conversation record has each request's carried context.`;
237
+ }
220
238
  /** The checks that keep a goal_satisfied session from counting as a pass, with their warnings. */
221
239
  export function judgeParticipantSession(session, deps, warnings) {
222
240
  const noEngagement = session !== undefined && hollowCompletion(sessionEnding(session));
223
241
  if (noEngagement) {
224
- warnings.push("Actor returned goal_satisfied with ZERO actions and ZERO messages — it likely saw a blank or still-loading screen and stopped without engaging. NOT counted as a pass. Check the screenshot; raise execution.timeoutMs or confirm the subject painted before the first turn.");
242
+ warnings.push("The participant returned goal_satisfied with no actions and no messages, so it likely saw a blank or loading screen and stopped. This does not count as a pass. Check the screenshot, and raise execution.timeoutMs or confirm the app had rendered before the first turn.");
225
243
  }
226
244
  const blockerReason = resolveSelfReportedBlocker(session);
227
245
  const selfReportedBlocker = blockerReason !== undefined;
228
246
  const reportedFriction = resolveSelfReportedFriction(session) !== undefined;
229
247
  if (selfReportedBlocker) {
230
- warnings.push(`Actor returned goal_satisfied while its final message describes a blocker or asks for missing instructions — NOT counted as a pass: ${redactText(deps.scrubKnownValues(blockerReason))}`);
248
+ warnings.push(`The participant returned goal_satisfied, but its final message describes a blocker or asks for missing instructions, so this does not count as a pass: ${redactText(deps.scrubKnownValues(blockerReason))}`);
231
249
  }
232
250
  return { noEngagement, selfReportedBlocker, reportedFriction };
233
251
  }
@@ -5,7 +5,7 @@ import { type LabTask } from "../../lab/tasks.js";
5
5
  import type { DesktopParticipantRun } from "./types.js";
6
6
  export declare const DEFAULT_MISSION = "You are testing a web application. The browser is already open at the subject URL. Explore it, accomplish what the scenario asks, and stop when done.";
7
7
  /**
8
- * The participant's outcome as ONE fixed first line of its last message (#570, second half). The
8
+ * The participant's outcome as one fixed first line of its last message. The
9
9
  * free-text computer-use provider has no schema to fill; a fixed line is the next best thing, and
10
10
  * the loop reads it into the trace's declaredOutcome. Prompt-only control is weak in general, so
11
11
  * adherence is measured (declaredOutcome present or absent on the trace) and the regex over the
@@ -21,24 +21,24 @@ export declare function composeParticipantInstructions(args: {
21
21
  mission: string;
22
22
  persona?: string;
23
23
  instruction?: string;
24
- /** The lab's declared protocol (#414). Only the participant-facing `goal` halves are rendered
24
+ /** The lab's declared protocol. Only the participant-facing `goal` halves are rendered
25
25
  * into the prompt; the `success` criteria never appear here. */
26
26
  tasks?: readonly LabTask[];
27
27
  device: {
28
28
  name: string;
29
29
  preset: DevicePreset;
30
30
  };
31
- /** The COMPILED persona for `args.persona`, when its committed file resolved (#381). Supplying it
32
- * makes the persona shape behavior — its traits become directives in the prompt and land in
33
- * traitsApplied — instead of appearing as a bare `Persona: <id>.` label. Absent (unsafe id,
34
- * no committed file, unparseable YAML) keeps the honest fallback: the bare line and an EMPTY
31
+ /** The compiled persona for `args.persona`, when its committed file resolved. Supplying it
32
+ * makes the persona shape behavior: its traits become directives in the prompt and land in
33
+ * traitsApplied, instead of appearing as a bare `Persona: <id>.` label. Absent (unsafe id,
34
+ * no committed file, unparseable YAML) keeps the fallback: the bare line and an empty
35
35
  * traitsApplied, never fabricated traits. Resolved by the caller so this stays pure. */
36
36
  resolvedPersona?: ResolvedPersona;
37
37
  /**
38
- * desktop-cli (#495): the surface under study is a terminal window, not a page. Said plainly
39
- * because a participant whose every prior world was a browser will look for one — and because a
38
+ * desktop-cli: the surface under study is a terminal window, not a page. Said plainly
39
+ * because a participant whose every prior world was a browser will look for one, and because a
40
40
  * capability nobody declares is one the recording cannot later be read against. It states that a
41
- * terminal is open and NOT what to type in it: naming commands would answer the question the
41
+ * terminal is open and does not say what to type in it: naming commands would answer the question the
42
42
  * study is asking.
43
43
  */
44
44
  surface?: "desktop-cli";
@@ -46,8 +46,8 @@ export declare function composeParticipantInstructions(args: {
46
46
  instructions: string;
47
47
  persona: ActorPersonaRef;
48
48
  };
49
- /** Runtime-inject the persona inbox instruction into a participant's prompt (#297 slice B). The inbox URL is a
50
- * runtime loopback/getHost address (not secret), so — mirroring the lobby-code runtime injection — this
49
+ /** Runtime-inject the persona inbox instruction into a participant's prompt. The inbox URL is a
50
+ * runtime loopback/getHost address (not secret), so, mirroring the lobby-code runtime injection, this
51
51
  * augments only the instructions the model receives; the authored prompt + its digest are unchanged.
52
52
  * Returns a new spec (never mutates). Shared by the CUA + concurrent shared-world routes. */
53
53
  export declare function withInboxMission(spec: DesktopParticipantRun, inboxUrl: string, address?: string, receiving?: boolean): DesktopParticipantRun;
@@ -7,7 +7,7 @@ import { personaBrief, personaToDirectives, renderPersonaPromptSection, } from "
7
7
  import { renderTaskPrompt } from "../../lab/tasks.js";
8
8
  export const DEFAULT_MISSION = "You are testing a web application. The browser is already open at the subject URL. Explore it, accomplish what the scenario asks, and stop when done.";
9
9
  /**
10
- * The participant's outcome as ONE fixed first line of its last message (#570, second half). The
10
+ * The participant's outcome as one fixed first line of its last message. The
11
11
  * free-text computer-use provider has no schema to fill; a fixed line is the next best thing, and
12
12
  * the loop reads it into the trace's declaredOutcome. Prompt-only control is weak in general, so
13
13
  * adherence is measured (declaredOutcome present or absent on the trace) and the regex over the
@@ -26,12 +26,12 @@ export function composeParticipantInstructions(args) {
26
26
  const deviceLine = preset.isMobile
27
27
  ? `You are a mobile user on a ${name} device (${preset.width}x${preset.height} @${preset.deviceScaleFactor}x). Expect a mobile/touch layout.`
28
28
  : `You are a desktop user (${name}, ${preset.width}x${preset.height}).`;
29
- // The protocol as the PARTICIPANT reads it: numbered goals, nothing else. The success criteria
30
- // are the researcher's instrument and must never reach this prompt — a persona told how it will
29
+ // The protocol as the participant reads it: numbered goals, nothing else. The success criteria
30
+ // are the researcher's instrument and must never reach this prompt: a persona told how it will
31
31
  // be measured optimizes for the measurement instead of using the product (src/lab/tasks.ts).
32
32
  const taskLines = renderTaskPrompt(args.tasks ?? []);
33
33
  // A resolved persona contributes its compiled directives (friction tolerance, skill bias,
34
- // accessibility behavior, constraints) through the SAME persona.ts compiler the terminal route
34
+ // accessibility behavior, constraints) through the same persona.ts compiler the terminal route
35
35
  // uses, so one persona file means one behavior across every route.
36
36
  const personaLine = args.resolvedPersona
37
37
  ? renderPersonaPromptSection(args.resolvedPersona)
@@ -64,8 +64,8 @@ export function composeParticipantInstructions(args) {
64
64
  },
65
65
  };
66
66
  }
67
- /** Runtime-inject the persona inbox instruction into a participant's prompt (#297 slice B). The inbox URL is a
68
- * runtime loopback/getHost address (not secret), so — mirroring the lobby-code runtime injection — this
67
+ /** Runtime-inject the persona inbox instruction into a participant's prompt. The inbox URL is a
68
+ * runtime loopback/getHost address (not secret), so, mirroring the lobby-code runtime injection, this
69
69
  * augments only the instructions the model receives; the authored prompt + its digest are unchanged.
70
70
  * Returns a new spec (never mutates). Shared by the CUA + concurrent shared-world routes. */
71
71
  export function withInboxMission(spec, inboxUrl, address, receiving = false) {
@@ -13,17 +13,17 @@ export declare function defaultSessionTimeoutMs(config: LabConfig): number;
13
13
  * costs the same wall-clock room either way. */
14
14
  export declare function resolveParticipantSandboxMs(config: LabConfig): number;
15
15
  /**
16
- * The in-flight participant bound a lab declares. Defaults to the participant count — every
16
+ * The in-flight participant bound a lab declares. Defaults to the participant count: every
17
17
  * declared participant runs at once, because a throttle nobody asked for silently turns "N actors
18
- * live" into waves (#350); total session count and spend are the same either way, only wall-clock
19
- * and simultaneity differ. A declared execution.concurrency is a CAP, clamped to [1, participants].
18
+ * live" into waves; total session count and spend are the same either way, only wall-clock
19
+ * and simultaneity differ. A declared execution.concurrency is a cap, clamped to [1, participants].
20
20
  * The planner records it; the route may only lower it from the environment.
21
21
  */
22
22
  export declare function boundedConcurrency(declared: number | undefined, participantCount: number): number;
23
23
  /**
24
- * Pure pre-flight plan resolver (runs in dry-run AND live). Returns the participant table, the
24
+ * Pure pre-flight plan resolver (runs in dry-run and live). Returns the participant table, the
25
25
  * effective concurrency, the wave count, the per-participant session budget, and the worst-case total
26
- * sandbox-minutes — BEFORE any sandbox or provider call. The same plan appears in dry-run,
26
+ * sandbox-minutes, before any sandbox or provider call. The same plan appears in dry-run,
27
27
  * marked $0 (dryRun: true).
28
28
  */
29
29
  export declare function resolveCuaParticipantPlan(config: LabConfig, opts?: {
@@ -32,8 +32,8 @@ export declare function resolveCuaParticipantPlan(config: LabConfig, opts?: {
32
32
  dryRun?: boolean;
33
33
  personas?: Map<string, ResolvedPersona>;
34
34
  }): CuaParticipantPlan;
35
- /** Print the participant plan to stderr BEFORE any sandbox/provider call (public-safe: ids, devices,
36
- * digests, and budgets only — no prompt text, no secrets). */
35
+ /** Print the participant plan to stderr before any sandbox/provider call (public-safe: ids, devices,
36
+ * digests, and budgets only; no prompt text, no secrets). */
37
37
  export declare function emitPreflightPlan(participantPlan: CuaParticipantPlan, labId: string): void;
38
38
  export declare function formatParticipantPlanEntry(entry: CuaParticipantPlanEntry): string;
39
39
  /**