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
@@ -9,7 +9,8 @@ import { describeMissingKeys } from "../../keys/key-resolution.js";
9
9
  import { prepareSelectedOutputDirectory } from "../../run/contained-output.js";
10
10
  import { evidenceAppUrlOf } from "./plan.js";
11
11
  import { resolveScriptedScenario } from "./scenario.js";
12
- import { SCRIPTED_BROWSER_LAB_SCHEMA, } from "./types.js";
12
+ import {} from "./types.js";
13
+ import { studyResultIdentity } from "../../run/study-result.js";
13
14
  // Journey wall-clock budget per surface: 5 minutes. A scripted surface has zero model cost and
14
15
  // sandbox-seconds are pennies; a short default only truncated slow-loading subjects.
15
16
  const DEFAULT_SESSION_TIMEOUT_MS = 300_000;
@@ -27,10 +28,9 @@ export async function prepareScriptedRun(plan, input) {
27
28
  const clone = plan.subject.kind === "clone" ? plan.subject : undefined;
28
29
  const evidenceAppUrl = evidenceAppUrlOf(plan.subject);
29
30
  const failed = (code, message) => ({
30
- schema: SCRIPTED_BROWSER_LAB_SCHEMA,
31
+ ...studyResultIdentity("scripted", plan.labId),
31
32
  ok: false,
32
33
  cwd,
33
- labId: plan.labId,
34
34
  actor: plan.actor,
35
35
  appUrl: evidenceAppUrl,
36
36
  dryRun,
@@ -58,7 +58,7 @@ export async function prepareScriptedRun(plan, input) {
58
58
  if (!scenario.ok) {
59
59
  return {
60
60
  ok: false,
61
- result: failed("HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID", scenario.message),
61
+ result: failed("HUMANISH_SCRIPTED_SCENARIO_INVALID", scenario.message),
62
62
  };
63
63
  }
64
64
  const journey = scenario.journey;
@@ -67,14 +67,14 @@ export async function prepareScriptedRun(plan, input) {
67
67
  if (missing.length > 0) {
68
68
  return {
69
69
  ok: false,
70
- result: failed("HUMANISH_SCRIPTED_LAB_KEYS_MISSING", `Live clone scripted-browser labs require ${missing.join(" and ")} (dry-run remains $0 and does not provision a subject). ${describeMissingKeys(missing, env)}`),
70
+ result: failed("HUMANISH_SCRIPTED_KEYS_MISSING", `Live clone scripted-browser labs require ${missing.join(" and ")} (dry-run remains $0 and does not provision a subject). ${describeMissingKeys(missing, env)}`),
71
71
  };
72
72
  }
73
73
  const unsetSubjectEnv = missingSubjectEnv(plan.requirements, env);
74
74
  if (unsetSubjectEnv.length > 0) {
75
75
  return {
76
76
  ok: false,
77
- result: failed("HUMANISH_SCRIPTED_LAB_SUBJECT_ENV_MISSING", `Subject env values missing for live clone scripted-browser lab: ${unsetSubjectEnv.join(", ")}.`),
77
+ result: failed("HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING", `Subject env values missing for live clone scripted-browser lab: ${unsetSubjectEnv.join(", ")}.`),
78
78
  };
79
79
  }
80
80
  const surfaces = plan.surfaces;
@@ -93,7 +93,7 @@ export async function prepareScriptedRun(plan, input) {
93
93
  if (!resolved) {
94
94
  return {
95
95
  ok: false,
96
- result: failed("HUMANISH_SCRIPTED_LAB_BROWSER_MISSING", "No Chrome/Chromium browser command was found for the scripted-browser actor. Set HUMANISH_BROWSER_COMMAND to a browser binary playwright-core can launch."),
96
+ result: failed("HUMANISH_SCRIPTED_BROWSER_MISSING", "No Chrome/Chromium browser command was found for the scripted-browser actor. Set HUMANISH_BROWSER_COMMAND to a browser binary playwright-core can launch."),
97
97
  };
98
98
  }
99
99
  browserCommand = resolved;
@@ -75,7 +75,7 @@ export class ScriptedSubject {
75
75
  mode: "scripted-browser-lab",
76
76
  tool: "humanish",
77
77
  labId: plan.labId,
78
- role: "subject",
78
+ kind: "subject",
79
79
  actor: plan.actor,
80
80
  },
81
81
  ...(subjectEnvNames.length > 0
@@ -18,7 +18,7 @@ export function scriptedSurfaceRecords(context, surface, index, result, screensh
18
18
  : "contract_proof_only";
19
19
  const reason = result?.reason ??
20
20
  context.sessionError ??
21
- "Contract bundle only: dry-run pinned the scenario contract without launching a browser or touching the subject app.";
21
+ "Dry run: the scenario was pinned without launching a browser or touching the subject app.";
22
22
  const simulation = participantRecord(ids, index + 1, {
23
23
  personaId: context.persona.id,
24
24
  scenarioId: context.journey.scenarioId,
@@ -31,13 +31,13 @@ export function scriptedSurfaceRecords(context, surface, index, result, screensh
31
31
  ? `Scripted-browser actor (${context.actorId}) replayed ${context.journey.scenarioId} on the ${surface.id} surface; ${result.completionReason}.`
32
32
  : context.sessionError !== undefined
33
33
  ? `Scripted lab failed before a terminal session verdict: ${context.sessionError}`
34
- : `Contract participant for the scripted-browser actor (${context.actorId}) against ${context.appUrl}.`,
34
+ : `Scripted-browser actor (${context.actorId}) against ${context.appUrl}; no session ran.`,
35
35
  startedAt: context.createdAt,
36
36
  updatedAt: result?.capture.capturedAt ?? context.createdAt,
37
37
  });
38
38
  const stream = participantStream(ids, {
39
39
  kind: "browser",
40
- label: `${surface.label} — ${context.labId}`,
40
+ label: `${surface.label} · ${context.labId}`,
41
41
  status,
42
42
  transport: "snapshot",
43
43
  updatedAt: result?.capture.capturedAt ?? context.createdAt,
@@ -6,7 +6,7 @@ import type { ObserverResult } from "../../observer/render.js";
6
6
  import type { RunSubjectProvenance } from "../../run/bundle.js";
7
7
  import type { LabDeps } from "../../lab/lab-deps.js";
8
8
  import type { RunLabHomes } from "../../lab/run-lab-homes.js";
9
- export declare const SCRIPTED_BROWSER_LAB_SCHEMA = "humanish.scripted-lab-result.v1";
9
+ import { type StudyResultIdentity } from "../../run/study-result.js";
10
10
  /** What a scripted run takes besides its plan. The plan carries the config, dry run and lab. */
11
11
  export type ScriptedRunInput = Omit<RunScriptedBrowserLabOptions, "config" | "dryRun" | "lab">;
12
12
  export interface RunScriptedBrowserLabOptions {
@@ -34,14 +34,12 @@ interface ScriptedBrowserLabSession {
34
34
  reason: string;
35
35
  screenshots: number;
36
36
  }
37
- export interface ScriptedBrowserLabResult extends AutomaticAnalysisResult {
38
- schema: typeof SCRIPTED_BROWSER_LAB_SCHEMA;
37
+ export interface ScriptedBrowserLabResult extends AutomaticAnalysisResult, StudyResultIdentity<"scripted"> {
39
38
  /** True when the bundle verified and (dry-run, or every session reached a terminal verdict
40
39
  * without a harness error). The subject failing the script is successful evidence, and the lab
41
40
  * does not fail for it. */
42
41
  ok: boolean;
43
42
  cwd: string;
44
- labId: string;
45
43
  /** The registry-resolved actor id that ran (or would run) the sessions. */
46
44
  actor: string;
47
45
  appUrl: string;
@@ -64,7 +62,7 @@ export interface ScriptedBrowserLabResult extends AutomaticAnalysisResult {
64
62
  observer?: ObserverResult;
65
63
  warnings: string[];
66
64
  error?: {
67
- code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_FAILED" | "HUMANISH_SCRIPTED_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_LAB_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_LAB_SUBJECT_UNSAFE" | "HUMANISH_SCRIPTED_LAB_BROWSER_MISSING" | "HUMANISH_SCRIPTED_LAB_KEYS_MISSING" | "HUMANISH_SCRIPTED_LAB_SUBJECT_ENV_MISSING" | "HUMANISH_SCRIPTED_LAB_GETHOST_UNAVAILABLE" | "HUMANISH_RUN_ID_IN_USE";
65
+ code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_SCRIPTED_FAILED" | "HUMANISH_SCRIPTED_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_SUBJECT_UNSAFE" | "HUMANISH_SCRIPTED_BROWSER_MISSING" | "HUMANISH_SCRIPTED_KEYS_MISSING" | "HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING" | "HUMANISH_SCRIPTED_GETHOST_UNAVAILABLE" | "HUMANISH_RUN_ID_IN_USE";
68
66
  message: string;
69
67
  };
70
68
  }
@@ -1,2 +1,2 @@
1
1
  // The scripted-browser lab's schema constant, options and result types.
2
- export const SCRIPTED_BROWSER_LAB_SCHEMA = "humanish.scripted-lab-result.v1";
2
+ import {} from "../../run/study-result.js";
@@ -14,7 +14,8 @@ function participantView(ctx, spec, index) {
14
14
  const session = outcome?.session;
15
15
  const screenshots = outcome?.screenshots ?? [];
16
16
  const lastScreenshot = screenshots[screenshots.length - 1];
17
- // public-safe (origin redacted): external-public seats open the public plane; getHost seats a seat path.
17
+ // public-safe (origin redacted): external-public participants open the public plane; getHost
18
+ // participants open their own path.
18
19
  const route = external
19
20
  ? "[external-public-plane]"
20
21
  : publicSafeRouteLabel(args.plan.plane.participants[index]?.entry);
@@ -29,7 +30,7 @@ function participantView(ctx, spec, index) {
29
30
  outcome?.sessionError ??
30
31
  (inProgress
31
32
  ? "Actor desktop is running; the attached Observer hydrates the runtime stream URL without persisting it."
32
- : "Contract actor only: dry-run produced the evidence shape without launching a desktop or spending provider tokens.");
33
+ : "Dry run: the evidence shape was written without launching a desktop or spending provider tokens.");
33
34
  const traceScreenshotMode = session?.trace.redaction.screenshots;
34
35
  // Include `declared` on the no-outcome fallback too (dry-run, skipped participant): otherwise an
35
36
  // absent `declared` means either "the preset rendered faithfully" or "there was no live
@@ -79,7 +80,7 @@ function sharedWorldSimulation(ctx, spec, index, view) {
79
80
  ? `Persona ${spec.planned.id}${taxonomy} failed before a terminal session verdict: ${outcome.sessionError}`
80
81
  : inProgress
81
82
  ? `Persona ${spec.planned.id}${taxonomy} (${spec.persona.id}) is running against the shared plane.`
82
- : `Contract persona ${spec.planned.id}${taxonomy} (${spec.persona.id}) for ${args.descriptor.id} against the shared plane at ${ctx.appUrl}.`,
83
+ : `Persona ${spec.planned.id}${taxonomy} (${spec.persona.id}) for ${args.descriptor.id} against the shared plane at ${ctx.appUrl}; no session ran.`,
83
84
  startedAt: args.run.createdAt,
84
85
  updatedAt: args.run.createdAt,
85
86
  });
@@ -92,7 +93,7 @@ function sharedWorldStream(ctx, spec, index, view) {
92
93
  ? {}
93
94
  : { assignment: participantAssignment(spec.evidenceAssignment) }),
94
95
  kind: "browser",
95
- label: `Concurrent persona ${spec.planned.id}${taxonomy} — ${args.plan.labId}`,
96
+ label: `Concurrent persona ${spec.planned.id}${taxonomy} · ${args.plan.labId}`,
96
97
  status: view.status,
97
98
  transport: "snapshot",
98
99
  updatedAt: args.run.createdAt,
@@ -116,7 +117,7 @@ function sharedWorldStream(ctx, spec, index, view) {
116
117
  desktopGeometry,
117
118
  ui: {
118
119
  route: view.route,
119
- intent: `Watch persona ${spec.planned.id}${taxonomy} (${spec.persona.id}) drive the SHARED plane concurrently with the other personas.`,
120
+ intent: `Watch persona ${spec.planned.id}${taxonomy} (${spec.persona.id}) use the shared app at the same time as the other personas.`,
120
121
  state: view.reason,
121
122
  ...(session ? { actorStatus: session.status } : {}),
122
123
  ...(lastScreenshot ? { screenshotUrl: lastScreenshot } : {}),
@@ -137,7 +138,7 @@ function sharedWorldStream(ctx, spec, index, view) {
137
138
  : []),
138
139
  // Run-level comms evidence belongs to the one shared app, and to no persona: register it once, on
139
140
  // the first stream, so the bundle's existence-verify + public-safety scan cover it without
140
- // double-counting across seats.
141
+ // double-counting across participants.
141
142
  ...(index === 0 && args.commsArtifactPath
142
143
  ? [{ label: "comms thread", path: args.commsArtifactPath, kind: "log" }]
143
144
  : []),
@@ -170,7 +171,7 @@ function sharedWorldEvents(ctx, spec, view) {
170
171
  at: createdAt,
171
172
  level: session.status === "passed" ? "info" : "warn",
172
173
  type: `concurrent-shared-world.session.${session.completionReason}`,
173
- message: `Persona ${spec.planned.id}: ${session.status} — ${session.reason}`,
174
+ message: `Persona ${spec.planned.id}: ${session.status} (${session.reason})`,
174
175
  });
175
176
  }
176
177
  else if (outcome?.sessionError !== undefined) {
@@ -197,7 +198,7 @@ function sharedWorldEvents(ctx, spec, view) {
197
198
  at: createdAt,
198
199
  level: "info",
199
200
  type: "concurrent-shared-world.contract.ready",
200
- message: `Persona ${spec.planned.id}: dry-run contract actor ready; switch scenario.mode to live for a real concurrent session.`,
201
+ message: `Persona ${spec.planned.id}: dry-run actor ready; switch scenario.mode to live for a real concurrent session.`,
201
202
  });
202
203
  }
203
204
  return events;
@@ -1,17 +1,17 @@
1
1
  import { type RunBundle } from "../../run/bundle.js";
2
2
  import { type SharedWorldJudgment } from "../../run/judge.js";
3
3
  import { type ActorRunResult, type ConcurrentBundleArgs } from "./types.js";
4
- /** Max windows live at the same instant (sweep over start/end points). The honest simultaneity
4
+ /** Max windows live at the same instant (sweep over start/end points). The simultaneity
5
5
  * count: the participant count says how many existed; this says how many ever ran at once. */
6
6
  export declare function maxSimultaneousWindows(windows: Array<{
7
7
  startedAt: number;
8
8
  endedAt: number;
9
9
  }>): number;
10
10
  /**
11
- * The judgment for a shared-world bundle's inputs: how each seat ended, plus what the run observed
12
- * about its world: overlap, a state change under overlap on the provisioned plane, and lobby
13
- * convergence on the external-public plane. The bundle's verdict and the lab result's ok both read
14
- * it.
11
+ * The judgment for a shared-world bundle's inputs: how each participant ended, plus what the run
12
+ * observed about its world: overlap, a state change under overlap on the provisioned plane, and
13
+ * lobby convergence on the external-public plane. The bundle's verdict and the study result's ok
14
+ * both read it.
15
15
  */
16
16
  export declare function judgeSharedWorldRun(args: Omit<ConcurrentBundleArgs, "judgment">): SharedWorldJudgment;
17
17
  export declare function actorRunPassed(result: ActorRunResult | undefined): boolean;
@@ -1,4 +1,4 @@
1
- // Builds the run bundle for a concurrent shared-world run: per-seat simulations, streams and
1
+ // Builds the run bundle for a concurrent shared-world run: per-participant simulations, streams and
2
2
  // events, the sharedWorld evidence block and the review summary.
3
3
  import { receivingPublication } from "../../comms/receiving-runtime.js";
4
4
  import { redactText } from "../../evidence/redaction.js";
@@ -8,13 +8,13 @@ import { SHARED_WORLD_SCHEMA, concurrencyFacts, sharedWorldParticipantKeys, } fr
8
8
  import { commandDigestOf } from "../../subject/state.js";
9
9
  import { buildRunCostSummary, desktopSpanToMinutes } from "../../run/cost-summary.js";
10
10
  import { participantFactsOf } from "../computer-use/participant-facts.js";
11
- import { judgeSharedWorld, participantPassed, sharedWorldShortfall, } from "../../run/judge.js";
11
+ import { judgeSharedWorld, participantPassed, sharedWorldShortfall, verdictText, } from "../../run/judge.js";
12
12
  import { combineCheckpointDigest } from "./checkpoints.js";
13
13
  import { hostOriginDigest } from "./provenance.js";
14
14
  import { participantEvent, participantIds } from "../../run/participant-records.js";
15
15
  import { sharedWorldParticipantRecords } from "./bundle-records.js";
16
16
  import { CONCURRENT_ATTRIBUTION_LIMITS, EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS, } from "./types.js";
17
- /** Max windows live at the same instant (sweep over start/end points). The honest simultaneity
17
+ /** Max windows live at the same instant (sweep over start/end points). The simultaneity
18
18
  * count: the participant count says how many existed; this says how many ever ran at once. */
19
19
  export function maxSimultaneousWindows(windows) {
20
20
  const points = windows
@@ -34,10 +34,10 @@ export function maxSimultaneousWindows(windows) {
34
34
  return max;
35
35
  }
36
36
  /**
37
- * The judgment for a shared-world bundle's inputs: how each seat ended, plus what the run observed
38
- * about its world: overlap, a state change under overlap on the provisioned plane, and lobby
39
- * convergence on the external-public plane. The bundle's verdict and the lab result's ok both read
40
- * it.
37
+ * The judgment for a shared-world bundle's inputs: how each participant ended, plus what the run
38
+ * observed about its world: overlap, a state change under overlap on the provisioned plane, and
39
+ * lobby convergence on the external-public plane. The bundle's verdict and the study result's ok
40
+ * both read it.
41
41
  */
42
42
  export function judgeSharedWorldRun(args) {
43
43
  const external = (args.planeClass ?? "provisioned-getHost") === "external-public";
@@ -68,7 +68,7 @@ export function actorRunPassed(result) {
68
68
  *
69
69
  * None of those is adopter-scored proof that the mission text was completed. In particular, a
70
70
  * productive `budget_reached` session can coexist with lobby convergence without becoming a
71
- * `goal_satisfied` result (#364).
71
+ * `goal_satisfied` result.
72
72
  */
73
73
  function formatSharedWorldActorOutcomes(outcomes, expectedCount) {
74
74
  const passedSessions = outcomes.filter((outcome) => outcome.ok).length;
@@ -97,7 +97,7 @@ function planeEvents(args, external) {
97
97
  at: createdAt,
98
98
  level: "info",
99
99
  type: "concurrent-shared-world.run.created",
100
- message: `Created CONCURRENT shared-world run for ${plan.labId} (actor ${descriptor.id}, ${actorSpecs.length} persona(s) vs ONE shared plane, max ${plan.concurrency} concurrent).`,
100
+ message: `Created a concurrent shared-world run for ${plan.labId} (actor ${descriptor.id}, ${actorSpecs.length} persona(s) on one shared app, at most ${plan.concurrency} at once).`,
101
101
  });
102
102
  // Human-readable plane label, byte-stable for the clone route. local-tree has no repo slug: it
103
103
  // labels the packed archive instead (archiveSha256 + dirty/clean when the packed root was a git
@@ -120,19 +120,21 @@ function planeEvents(args, external) {
120
120
  level: "info",
121
121
  type: "concurrent-shared-world.plane.provenance",
122
122
  message: external
123
- ? `Shared plane: an EXTERNAL-PUBLIC deployment (operator-attested owner ${externalPlaneOwner}, authorized) used DIRECTLY as the shared plane, with NO getHost, clone, subject sandbox, or seed. The harness OBSERVES that each participant reached the operator-declared origin (publicOriginDigest); it did NOT mint or control the plane. Author-trust ownership attestation, NOT a synthetic-data claim.`
123
+ ? `Shared app: a public deployment the operator declares they own (${externalPlaneOwner}, authorized), used as it is, with no sandbox, clone or seed. humanish observed that each participant reached the declared origin (publicOriginDigest); it did not create or control the app. Ownership is the lab's declaration, and the data is not claimed to be synthetic.`
124
124
  : dryRun
125
- ? `Shared plane declared: ${dryRunPlaneLabel}, served + getHost-exposed in-sandbox (dry-run contract; nothing ${args.subject.source === "local-tree" ? "packed" : "cloned"}). Seed recipe ${args.seedDigest}; SYNTHETIC subject (author-attested); env names: ${args.subject.envNames?.join(", ") || "none"} (values never persisted).`
126
- : `Shared plane: ${livePlaneLabel}, served + exposed at the harness-minted getHost URL; seed recipe ${args.seedDigest}; SYNTHETIC subject (author-attested); env names: ${args.subject.envNames?.join(", ") || "none"} (values never persisted).`,
125
+ ? `Shared app declared: ${dryRunPlaneLabel}, to be served in the sandbox at a public sandbox URL (dry run: nothing ${args.subject.source === "local-tree" ? "packed" : "cloned"}). Seed recipe ${args.seedDigest}; synthetic subject, as the study declares; env names: ${args.subject.envNames?.join(", ") || "none"} (values never stored).`
126
+ : `Shared app: ${livePlaneLabel}, served at a public sandbox URL humanish created; seed recipe ${args.seedDigest}; synthetic subject, as the study declares; env names: ${args.subject.envNames?.join(", ") || "none"} (values never stored).`,
127
127
  }));
128
128
  return events;
129
129
  }
130
- /** The sharedWorld block: seat windows, the state series, seat outcomes and the plane. */
130
+ /** The sharedWorld block: participant windows, the state series, participant outcomes and the
131
+ * plane. */
131
132
  function sharedWorldEvidence(args, external, inProgress, planeCommit) {
132
133
  const { plan, dryRun, actorSpecs, actorResults } = args;
133
134
  // Build the concurrent shared-world evidence block. routeHostDigest is sha256-16 of the origin each
134
- // seat reached: on getHost the seat URL the actor drove (verify confirms == plane.hostDigest); on
135
- // external-public the seat's CDP-OBSERVED URL origin (verify confirms == plane.publicOriginDigest).
135
+ // participant reached: on getHost the participant URL the actor drove (verify confirms ==
136
+ // plane.hostDigest); on external-public the participant's CDP-observed URL origin (verify
137
+ // confirms == plane.publicOriginDigest).
136
138
  const fallbackHostDigest = external
137
139
  ? (args.publicOriginDigest ?? commandDigestOf("[external-public-plane]"))
138
140
  : (args.hostDigest ?? commandDigestOf("[provisioned-subject]"));
@@ -189,7 +191,7 @@ function sharedWorldEvidence(args, external, inProgress, planeCommit) {
189
191
  seedDigest: args.seedDigest,
190
192
  envNames: [],
191
193
  // publicOriginDigest is the observed convergence origin; declaredOriginDigest records the
192
- // operator-declared origin for reference (a redirect makes them differ — not a failure).
194
+ // operator-declared origin for reference (a redirect that makes them differ is no failure).
193
195
  ...(args.publicOriginDigest === undefined
194
196
  ? {}
195
197
  : { publicOriginDigest: args.publicOriginDigest }),
@@ -226,8 +228,8 @@ function sharedWorldEvidence(args, external, inProgress, planeCommit) {
226
228
  return { sharedWorld, windows, stateSeries, outcomes };
227
229
  }
228
230
  /**
229
- * A finished run's gaps: each seat that did not pass, or, when every seat passed, the world
230
- * shortfall that failed the run.
231
+ * A finished run's gaps: each participant that did not pass, or, when every participant passed, the
232
+ * world shortfall that failed the run.
231
233
  */
232
234
  function finishedGaps(actorResults, shortfall) {
233
235
  const participantGaps = actorResults
@@ -249,10 +251,10 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
249
251
  ? "stateSeries omitted (no authoritative shared-state proof on the external-public plane)"
250
252
  : `stateSeries ${(stateSeries ?? []).length} snapshot(s), ${deltas} delta(s)`;
251
253
  const convergenceLabel = external
252
- ? `; lobby convergence ${args.lobbyConvergenceDigest ? "PROVEN (all participants reached one /lobby/CODE)" : "not observed"}`
254
+ ? `; lobby convergence ${args.lobbyConvergenceDigest ? "shown (all participants reached one /lobby/CODE)" : "not observed"}`
253
255
  : "";
254
256
  // The count that matters is how many participants were live at once, which can be fewer than exist:
255
- // a 6-participant run capped at 3 must never read as 6-wide concurrency (#350, the field failure).
257
+ // a 6-participant run capped at 3 must never read as 6-wide concurrency.
256
258
  const capForReport = plan.concurrency;
257
259
  const maxLive = maxSimultaneousWindows(windows);
258
260
  events.push({
@@ -260,11 +262,11 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
260
262
  at: createdAt,
261
263
  level: "info",
262
264
  type: "concurrent-shared-world.concurrency",
263
- message: `Concurrency: ${windows.length} participant(s)${dryRun ? " (dry-run contract; $0)" : `, up to ${maxLive} live at once (cap ${capForReport}), overlap ${overlaps ? "PROVEN" : "not observed"}`}; ${stateSeriesLabel}${convergenceLabel}. Attribution ceiling: ${sharedWorld.attributionLimits.join(", ")}. ${dryRun ? "This contract-only run proves no live concurrency, scale, or adoption." : "This run reports only its own observed overlap and state changes; it does not prove scale, repeatability, or adopter-harness replacement."}`,
265
+ message: `Concurrency: ${windows.length} participant(s)${dryRun ? " (dry run; $0)" : `, up to ${maxLive} live at once (cap ${capForReport}), overlap ${overlaps ? "shown" : "not observed"}`}; ${stateSeriesLabel}${convergenceLabel}. Attribution ceiling: ${sharedWorld.attributionLimits.join(", ")}. ${dryRun ? "This dry run proves nothing about live concurrency, scale, or adoption." : "This run reports only its own observed overlap and state changes; it does not prove scale, repeatability, or adopter-harness replacement."}`,
264
266
  });
265
- // The judge's verdict (judgeSharedWorld): every seat produced a terminal, engaged, passed session.
266
- // Mission endpoint and completion reasons are reported separately below; `outcomes[].ok` is not
267
- // renamed into mission success (#364).
267
+ // The judge's verdict (judgeSharedWorld): every participant produced a terminal, engaged, passed
268
+ // session. Mission endpoint and completion reasons are reported separately below; `outcomes[].ok`
269
+ // is not renamed into mission success.
268
270
  const verdict = args.judgment.verdict;
269
271
  const actorOutcomeSummary = formatSharedWorldActorOutcomes(outcomes, actorSpecs.length);
270
272
  const review = {
@@ -272,19 +274,19 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
272
274
  verdict,
273
275
  // Plane-class-aware: the external-public plane has no getHost/clone/seed and carries no
274
276
  // authoritative state series, so its summary must not claim a getHost-exposed plane (dry-run) nor
275
- // report "state delta(s) under load" (live) — it reports lobby convergence instead.
277
+ // report "state delta(s) under load" (live). It reports lobby convergence instead.
276
278
  summary: dryRun
277
279
  ? external
278
- ? `Dry-run concurrent shared-world contract: ${actorSpecs.length} persona(s) declared against ONE external-public shared plane (a real public deployment used directly; no getHost/clone/seed); no sandboxes launched, $0 spend.`
279
- : `Dry-run concurrent shared-world contract: ${actorSpecs.length} persona(s) declared against ONE getHost-exposed plane (${descriptor.id}); no sandboxes launched, $0 spend.`
280
+ ? `Concurrent shared-world dry run: ${actorSpecs.length} persona(s) declared against one public deployment, used as it is (no sandbox, clone or seed); no sandboxes launched, $0 spent.`
281
+ : `Concurrent shared-world dry run: ${actorSpecs.length} persona(s) declared against one app served at a public sandbox URL (${descriptor.id}); no sandboxes launched, $0 spent.`
280
282
  : inProgress
281
- ? `In-progress concurrent shared-world Observer snapshot: ${actorSpecs.length} persona(s) running against ONE shared plane; final verification is pending.`
283
+ ? `In-progress concurrent shared-world Observer snapshot: ${actorSpecs.length} persona(s) running against one shared app; final verification is pending.`
282
284
  : external
283
- ? `Concurrent shared-world (ONE external-public plane, ${actorSpecs.length} simultaneous personas): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${args.lobbyConvergenceDigest ? `${actorSpecs.length} participants converged on one lobby` : "lobby convergence not observed"}.`
284
- : `Concurrent shared-world (ONE plane, ${actorSpecs.length} simultaneous personas): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${deltas} state delta(s) under load.`,
285
+ ? `Concurrent shared-world (one public deployment, ${actorSpecs.length} personas at once): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${args.lobbyConvergenceDigest ? `${actorSpecs.length} participants converged on one lobby` : "lobby convergence not observed"}.`
286
+ : `Concurrent shared-world (one shared app, ${actorSpecs.length} personas at once): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${deltas} state delta(s) under load.`,
285
287
  gaps: dryRun
286
288
  ? [
287
- "This dry-run launched no concurrent shared-world session; it proves contract shape only, not live behavior, scale, or adopter-harness replacement.",
289
+ "This dry run launched no concurrent shared-world session; it checks the evidence shape only, not live behavior, scale, or adopter-harness replacement.",
288
290
  ]
289
291
  : inProgress
290
292
  ? [
@@ -301,7 +303,7 @@ export function buildConcurrentSharedWorldBundle(args) {
301
303
  const external = (args.planeClass ?? "provisioned-getHost") === "external-public";
302
304
  const simulations = [];
303
305
  const streams = [];
304
- // Public-safe label only — neither the raw getHost URL (provisioned) nor the raw public origin
306
+ // Public-safe label only: neither the raw getHost URL (provisioned) nor the raw public origin
305
307
  // (external-public) lands in the bundle. The plane identity is a digest (plane.hostDigest on
306
308
  // getHost; plane.publicOriginDigest on external-public).
307
309
  const appUrl = external ? "[external-public-plane]" : "[provisioned-subject]";
@@ -331,7 +333,7 @@ export function buildConcurrentSharedWorldBundle(args) {
331
333
  persona: {
332
334
  id: actorSpecs[0]?.persona.id ?? "concurrent-persona",
333
335
  name: `Concurrent shared-world swarm (${actorSpecs.length} personas)`,
334
- source: `lab:${plan.labId}`,
336
+ source: `study:${plan.labId}`,
335
337
  sourceDigest: actorSpecs[0]?.persona.promptDigest ?? args.seedDigest,
336
338
  },
337
339
  scenario: {
@@ -340,14 +342,14 @@ export function buildConcurrentSharedWorldBundle(args) {
340
342
  goal: redactText(actorSpecs[0]?.evidenceInstructions ??
341
343
  actorSpecs[0]?.instructions ??
342
344
  "Concurrent shared-world interaction."),
343
- source: `lab:${plan.labId}`,
345
+ source: `study:${plan.labId}`,
344
346
  sourceDigest: actorSpecs[0]?.persona.promptDigest ?? args.seedDigest,
345
347
  },
346
348
  lifecycle: [
347
349
  {
348
350
  at: createdAt,
349
351
  event: "concurrent-shared-world.run.created",
350
- message: `Created concurrent shared-world run with ONE shared plane and ${actorSpecs.length} simultaneous participants (actor ${descriptor.id}).`,
352
+ message: `Created a concurrent shared-world run with one shared app and ${actorSpecs.length} participants at once (actor ${descriptor.id}).`,
351
353
  },
352
354
  ],
353
355
  simulations,
@@ -357,11 +359,11 @@ export function buildConcurrentSharedWorldBundle(args) {
357
359
  status: "passed",
358
360
  notes: ranLive
359
361
  ? anyRaw
360
- ? "Typed text recorded as length only and reasoning/messages pass through text redaction. Some personas captured FULL-FIDELITY (raw) screenshots, retained for local use — NOT redacted for publishing; set policies.redactScreenshots: true to blur a share-as-is bundle. stateSeries persists digest-only."
362
+ ? "Typed text is recorded as its length only, and reasoning and messages pass through text redaction. Some personas captured unblurred screenshots, kept for local use and not redacted for publishing. Set policies.redactScreenshots: true to blur screenshots in a bundle you plan to share. stateSeries stores digests only."
361
363
  : "Typed text recorded as length only and reasoning/messages pass through text redaction. Screenshots are blurred at capture (policies.redactScreenshots: true) for a share-as-is bundle. stateSeries persists digest-only."
362
364
  : inProgress
363
365
  ? "In-progress live Observer snapshot: runtime stream auth URLs are process-local only and are not persisted. Final typed text, traces, and screenshots are pending. stateSeries persists digest-only."
364
- : "Dry-run concurrent shared-world contract bundle: no sandboxes launched and no screenshots captured. Typed text is recorded as length only and reasoning/messages pass through text redaction whenever a session runs. stateSeries persists digest-only.",
366
+ : "Concurrent shared-world dry-run bundle: no sandboxes launched and no screenshots captured. Typed text is recorded as length only and reasoning/messages pass through text redaction whenever a session runs. stateSeries persists digest-only.",
365
367
  },
366
368
  artifacts: bundleArtifacts(),
367
369
  review,
@@ -429,7 +431,7 @@ export function renderConcurrentReviewMarkdown(bundle) {
429
431
  `- attribution class: ${bundle.attributionClass ?? "isolated"}`,
430
432
  `- topology: ${sw?.topology ?? "(none)"} / ${sw?.topologyMode ?? "(none)"}`,
431
433
  `- personas: ${sw?.roleCount ?? 0}`,
432
- `- verdict: ${bundle.review.verdict}`,
434
+ `- verdict: ${verdictText(bundle.review.verdict, bundle.mode)}`,
433
435
  `- summary: ${bundle.review.summary}`,
434
436
  ...(plane ? [`- plane: ${plane.message}`] : []),
435
437
  ...(concurrency ? [`- concurrency: ${concurrency.message}`] : []),
@@ -8,7 +8,7 @@ export declare function combineCheckpointDigest(parts: string[]): string;
8
8
  * Run one checkpoint snapshot live: each declared probe runs read-only via the detached
9
9
  * primitive; its stdout is literal-scrubbed (provisioned values + the probe's declared redact
10
10
  * literals, folded into `scrub`) then pattern-redacted, then digested. Only the combined digest
11
- * persists — never the raw value (the seed-step lockdown). Unique step names per snapshot prevent
11
+ * persists, never the raw value (the seed-step lockdown). Unique step names per snapshot prevent
12
12
  * stale-status reuse across snapshots.
13
13
  */
14
14
  export declare function runCheckpointSnapshot(args: {
@@ -14,7 +14,7 @@ export function combineCheckpointDigest(parts) {
14
14
  * Run one checkpoint snapshot live: each declared probe runs read-only via the detached
15
15
  * primitive; its stdout is literal-scrubbed (provisioned values + the probe's declared redact
16
16
  * literals, folded into `scrub`) then pattern-redacted, then digested. Only the combined digest
17
- * persists — never the raw value (the seed-step lockdown). Unique step names per snapshot prevent
17
+ * persists, never the raw value (the seed-step lockdown). Unique step names per snapshot prevent
18
18
  * stale-status reuse across snapshots.
19
19
  */
20
20
  export async function runCheckpointSnapshot(args) {
@@ -14,7 +14,7 @@ export interface SubjectComms {
14
14
  }
15
15
  export declare function subjectCommsOf(config: Pick<LabConfig, "comms">, planeClass: ConcurrentSharedWorldPlaneClass): SubjectComms;
16
16
  /**
17
- * Adopter-hosted ingress (#328): on the external-public plane the harness provisions nothing, so
17
+ * Adopter-hosted ingress: on the external-public plane the harness provisions nothing, so
18
18
  * it cannot host a catch. The operator can, and then humanish still does every other part of
19
19
  * the funnel: it tells each persona its address and inbox URL, drains the declared catch over
20
20
  * HTTP at teardown, and writes the same digest-only evidence. Declaring `external` is what turns
@@ -26,11 +26,11 @@ export declare function prepareExternalComms(config: Pick<LabConfig, "comms">, p
26
26
  wiring: ExternalCommsWiring | undefined;
27
27
  } | {
28
28
  ok: false;
29
- code: "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_TOKEN_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE";
29
+ code: "HUMANISH_SHARED_WORLD_COMMS_TOKEN_INVALID" | "HUMANISH_SHARED_WORLD_COMMS_CATCH_UNREACHABLE";
30
30
  message: string;
31
31
  }>;
32
32
  /**
33
- * Off-app comms evidence (#297): drain everything the in-sandbox catch captured, route it into a
33
+ * Off-app comms evidence: drain everything the in-sandbox catch captured, route it into a
34
34
  * host fake inbox addressed to the declared recipients, and write the run-level digest-only thread
35
35
  * artifact while the subject is still alive, before it is killed. Wrapped so a drain error
36
36
  * never blocks teardown (invariant: all sandboxes torn down by id in the plane's finally). Returns
@@ -38,8 +38,8 @@ export declare function prepareExternalComms(config: Pick<LabConfig, "comms">, p
38
38
  */
39
39
  export declare function drainSubjectComms(ctx: PlaneContext, commsEmail: LabCommsEmail, subjectShell: Shell, deployedComms: DeployedCommsCatch): Promise<string | undefined>;
40
40
  /**
41
- * Adopter-hosted drain (#328/#387): same routing and digest-only artifact as the in-sandbox
42
- * catch — only the transport differs (HTTP GET /deliveries against the catch the operator
41
+ * Adopter-hosted drain: same routing and digest-only artifact as the in-sandbox
42
+ * catch. Only the transport differs (HTTP GET /deliveries against the catch the operator
43
43
  * runs). Called in the plane's finally so the evidence survives a failed run; a drain error never
44
44
  * masks the run's own outcome. Returns the thread's path when one was written.
45
45
  */
@@ -1,5 +1,5 @@
1
1
  // Off-app comms for the concurrent shared-world route: which email catch a plane gets (in the
2
- // subject sandbox, or adopter-hosted), and the drains that match captured mail to the seats'
2
+ // subject sandbox, or adopter-hosted), and the drains that match captured mail to the participants'
3
3
  // declared inboxes and write the digest-only thread.
4
4
  import { catchTokenOf, catchTokenRefusal, collectExternalCommsEvidence, } from "../../comms/external-evidence.js";
5
5
  import { FakeInbox } from "../../comms/fake-inbox.js";
@@ -8,9 +8,9 @@ import { DEFAULT_SANDBOX_CATCH_PORT, collectCommsThread, externalCatchHealthy, e
8
8
  import { redactText, toErrorMessage } from "../../evidence/redaction.js";
9
9
  import { writeContainedOutputFile } from "../../run/contained-output.js";
10
10
  import { addressedRecipients } from "../../lab/parse/comms.js";
11
- // Off-app comms (#297): on the provisioned-getHost plane the harness owns the one subject sandbox, so
11
+ // Off-app comms: on the provisioned-getHost plane the harness owns the one subject sandbox, so
12
12
  // it can redirect the app's email-API sends into an in-sandbox catch and evidence them. Gated entirely
13
- // on config.comms — no comms declared → zero change. The base-URL env is injected into the subject
13
+ // on config.comms: no comms declared → zero change. The base-URL env is injected into the subject
14
14
  // sandbox at create (fixed port known up front); the catch is deployed before serve; the drain + digest
15
15
  // evidence run at subject teardown, then register run-level in the bundle. Unavailable on the
16
16
  // external-public plane (the app is an operator-owned deployment the harness never provisions).
@@ -19,7 +19,7 @@ export function subjectCommsOf(config, planeClass) {
19
19
  ? config.comms.email
20
20
  : undefined;
21
21
  const commsPort = commsEmail ? (commsEmail.port ?? DEFAULT_SANDBOX_CATCH_PORT) : undefined;
22
- // injectEnv is absent on an adopter-hosted plane (#328): there is no subject env to inject
22
+ // injectEnv is absent on an adopter-hosted plane: there is no subject env to inject
23
23
  // because the operator points their own app at their own catch.
24
24
  const commsEnv = commsEmail?.injectEnv !== undefined && commsPort !== undefined
25
25
  ? { [commsEmail.injectEnv]: `http://127.0.0.1:${commsPort}` }
@@ -27,7 +27,7 @@ export function subjectCommsOf(config, planeClass) {
27
27
  return { email: commsEmail, port: commsPort, env: commsEnv };
28
28
  }
29
29
  /**
30
- * Adopter-hosted ingress (#328): on the external-public plane the harness provisions nothing, so
30
+ * Adopter-hosted ingress: on the external-public plane the harness provisions nothing, so
31
31
  * it cannot host a catch. The operator can, and then humanish still does every other part of
32
32
  * the funnel: it tells each persona its address and inbox URL, drains the declared catch over
33
33
  * HTTP at teardown, and writes the same digest-only evidence. Declaring `external` is what turns
@@ -40,7 +40,7 @@ export async function prepareExternalComms(config, planeClass, dryRun, warnings,
40
40
  if (config.comms?.email?.kind === "fake" &&
41
41
  planeClass === "external-public" &&
42
42
  externalComms === undefined) {
43
- warnings.push("comms.email is declared but this is the external-public plane (the shared plane is an operator-owned public deployment the harness does not provision) — the in-sandbox email catch cannot be deployed and no comms evidence is collected. Declare `comms.email.external` to host the catch yourself (#328).");
43
+ warnings.push("comms.email is declared, but this study drives a public deployment that humanish does not provision, so the email catch cannot run in a sandbox and no email evidence is collected. Run the catch yourself with `humanish comms catch` and declare `comms.email.external`.");
44
44
  }
45
45
  if (!externalComms || !externalCommsEmail)
46
46
  return { ok: true, wiring: undefined };
@@ -49,7 +49,7 @@ export async function prepareExternalComms(config, planeClass, dryRun, warnings,
49
49
  if (tokenRefusal !== undefined)
50
50
  return {
51
51
  ok: false,
52
- code: "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_TOKEN_INVALID",
52
+ code: "HUMANISH_SHARED_WORLD_COMMS_TOKEN_INVALID",
53
53
  message: tokenRefusal,
54
54
  };
55
55
  // Fail closed before any actor sandbox is created: a comms lab whose catch is unreachable
@@ -58,14 +58,14 @@ export async function prepareExternalComms(config, planeClass, dryRun, warnings,
58
58
  if (!dryRun && !(await externalCatchHealthy(externalComms))) {
59
59
  return {
60
60
  ok: false,
61
- code: "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE",
61
+ code: "HUMANISH_SHARED_WORLD_COMMS_CATCH_UNREACHABLE",
62
62
  message: `The external comms catch or inbox is unreachable or incompatible (GET /health must identify humanish-comms-catch and advertise recipient-inbox-v1). Update humanish on the catch host and restart it with \`humanish comms catch\` on that host, or drop comms.email to run without the inbox funnel.`,
63
63
  };
64
64
  }
65
65
  return { ok: true, wiring: { external: externalComms, email: externalCommsEmail, inboxUrl } };
66
66
  }
67
67
  /**
68
- * Off-app comms evidence (#297): drain everything the in-sandbox catch captured, route it into a
68
+ * Off-app comms evidence: drain everything the in-sandbox catch captured, route it into a
69
69
  * host fake inbox addressed to the declared recipients, and write the run-level digest-only thread
70
70
  * artifact while the subject is still alive, before it is killed. Wrapped so a drain error
71
71
  * never blocks teardown (invariant: all sandboxes torn down by id in the plane's finally). Returns
@@ -91,11 +91,11 @@ export async function drainSubjectComms(ctx, commsEmail, subjectShell, deployedC
91
91
  return "comms/thread.json";
92
92
  }
93
93
  else if (collected.captured > 0) {
94
- warnings.push(`Comms catch captured ${collected.captured} email send(s) but none matched a declared recipient inbox — no comms evidence written. Declare comms.email.recipients[].address to match the address the app sends to.`);
94
+ warnings.push(`The email catch captured ${collected.captured} email send(s), but none matched a declared recipient inbox, so no email evidence was written. Set comms.email.recipients[].address to the address the app sends to.`);
95
95
  }
96
96
  else {
97
- // Zero captures is the silent-broken shape (#351): the app never posted to the catch.
98
- warnings.push(`Comms catch captured ZERO email sends — the app never delivered mail through the catch. Verify the app reads ${commsEmail.injectEnv} for its email API base URL (an SDK that ignores it sends real mail or throws) and that the flow reached an email step.`);
97
+ // Zero captures is the silent-broken shape: the app never posted to the catch.
98
+ warnings.push(`The email catch captured no email sends: the app never delivered mail through it. Verify the app reads ${commsEmail.injectEnv} for its email API base URL (an SDK that ignores it sends real mail or throws) and that the flow reached an email step.`);
99
99
  }
100
100
  }
101
101
  catch (error) {
@@ -104,8 +104,8 @@ export async function drainSubjectComms(ctx, commsEmail, subjectShell, deployedC
104
104
  return undefined;
105
105
  }
106
106
  /**
107
- * Adopter-hosted drain (#328/#387): same routing and digest-only artifact as the in-sandbox
108
- * catch — only the transport differs (HTTP GET /deliveries against the catch the operator
107
+ * Adopter-hosted drain: same routing and digest-only artifact as the in-sandbox
108
+ * catch. Only the transport differs (HTTP GET /deliveries against the catch the operator
109
109
  * runs). Called in the plane's finally so the evidence survives a failed run; a drain error never
110
110
  * masks the run's own outcome. Returns the thread's path when one was written.
111
111
  */