humanish 0.106.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/AGENTS.md +4 -2
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +24 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -6
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +31 -4
  16. package/dist/actors/codex/qualified-versions.js +51 -6
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +10 -8
  45. package/dist/actors/contract.js +7 -1
  46. package/dist/actors/local-agent/cli.js +1 -1
  47. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  48. package/dist/actors/scripted-browser/journey.js +15 -4
  49. package/dist/actors/scripted-browser/steps.js +18 -0
  50. package/dist/actors/scripted-browser/types.d.ts +11 -1
  51. package/dist/actors/stop-conditions.js +1 -3
  52. package/dist/analysis/automatic-completion.d.ts +13 -8
  53. package/dist/analysis/automatic-completion.js +14 -8
  54. package/dist/analysis/automatic-config.d.ts +1 -1
  55. package/dist/analysis/automatic-config.js +2 -2
  56. package/dist/analysis/automatic.d.ts +10 -4
  57. package/dist/analysis/automatic.js +17 -13
  58. package/dist/analysis/diagnostics.d.ts +23 -0
  59. package/dist/analysis/diagnostics.js +112 -0
  60. package/dist/analysis/evidence-sources.js +2 -2
  61. package/dist/analysis/evidence.js +6 -6
  62. package/dist/analysis/execute.d.ts +7 -1
  63. package/dist/analysis/execute.js +39 -12
  64. package/dist/analysis/job.d.ts +8 -5
  65. package/dist/analysis/job.js +15 -14
  66. package/dist/analysis/load.d.ts +1 -1
  67. package/dist/analysis/load.js +5 -5
  68. package/dist/analysis/provider.d.ts +9 -1
  69. package/dist/analysis/restricted-codex.d.ts +2 -0
  70. package/dist/analysis/restricted-codex.js +10 -1
  71. package/dist/analysis/service.d.ts +2 -0
  72. package/dist/analysis/service.js +31 -12
  73. package/dist/analysis/sharing.d.ts +2 -2
  74. package/dist/analysis/sharing.js +5 -5
  75. package/dist/analysis/store-executions.d.ts +5 -5
  76. package/dist/analysis/store-executions.js +12 -12
  77. package/dist/analysis/store.d.ts +4 -4
  78. package/dist/analysis/store.js +13 -13
  79. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  80. package/dist/cli/commands/analysis-signals.js +4 -1
  81. package/dist/cli/commands/analyze.js +4 -2
  82. package/dist/cli/commands/comms.js +8 -1
  83. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  84. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  85. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  86. package/dist/cli/commands/lab-route-preview.js +3 -4
  87. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  88. package/dist/cli/commands/lab-route-run.js +6 -2
  89. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  90. package/dist/cli/commands/lab-route-scripted.js +0 -1
  91. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  92. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  93. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  94. package/dist/cli/commands/lab-route-terminal.js +0 -1
  95. package/dist/cli/commands/lab-run.js +76 -45
  96. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  97. package/dist/cli/commands/lab.js +12 -6
  98. package/dist/cli/commands/observe.js +22 -0
  99. package/dist/cli/commands/run-signals.d.ts +30 -0
  100. package/dist/cli/commands/run-signals.js +146 -0
  101. package/dist/cli/commands/runs.js +10 -8
  102. package/dist/cli/commands/watch.js +12 -10
  103. package/dist/cli/doctor.d.ts +3 -0
  104. package/dist/cli/doctor.js +10 -2
  105. package/dist/cli/io.d.ts +5 -4
  106. package/dist/cli/io.js +12 -8
  107. package/dist/cli/program.js +3 -3
  108. package/dist/cli/renamed-options.d.ts +11 -0
  109. package/dist/cli/renamed-options.js +18 -0
  110. package/dist/cli/telemetry.d.ts +2 -2
  111. package/dist/cli/telemetry.js +1 -1
  112. package/dist/comms/capture-surface.d.ts +1 -1
  113. package/dist/comms/catch-host.d.ts +1 -1
  114. package/dist/comms/connections.js +4 -4
  115. package/dist/comms/external-evidence.d.ts +27 -0
  116. package/dist/comms/external-evidence.js +93 -0
  117. package/dist/comms/lease-store.js +7 -7
  118. package/dist/comms/types.js +1 -1
  119. package/dist/evidence/browser-hygiene.d.ts +1 -1
  120. package/dist/evidence/browser-hygiene.js +1 -1
  121. package/dist/evidence/redaction.js +1 -1
  122. package/dist/evidence/secret-scrub.d.ts +9 -0
  123. package/dist/evidence/secret-scrub.js +96 -0
  124. package/dist/feedback/draft.js +7 -9
  125. package/dist/feedback/export-bundle.js +4 -4
  126. package/dist/feedback/export.js +9 -9
  127. package/dist/feedback/feedback.d.ts +1 -1
  128. package/dist/index.d.ts +3 -6
  129. package/dist/index.js +3 -6
  130. package/dist/keys/key-resolution.d.ts +3 -1
  131. package/dist/keys/key-resolution.js +18 -16
  132. package/dist/lab/adapter-extension.d.ts +28 -6
  133. package/dist/lab/adapter-extension.js +65 -126
  134. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  135. package/dist/lab/adapter-scorer-loader.js +24 -0
  136. package/dist/lab/composition-rules.d.ts +2 -0
  137. package/dist/lab/composition-rules.js +35 -26
  138. package/dist/lab/config.js +28 -26
  139. package/dist/lab/device-presets.d.ts +2 -2
  140. package/dist/lab/discover.js +1 -3
  141. package/dist/lab/doctor.d.ts +44 -9
  142. package/dist/lab/doctor.js +149 -41
  143. package/dist/lab/init-plan.js +1 -3
  144. package/dist/lab/keys.js +1 -1
  145. package/dist/lab/lab-deps.d.ts +85 -0
  146. package/dist/lab/lab-deps.js +4 -0
  147. package/dist/lab/parse/actors.js +8 -7
  148. package/dist/lab/parse/comms.js +3 -2
  149. package/dist/lab/parse/execution.js +3 -2
  150. package/dist/lab/parse/subject-state.js +2 -1
  151. package/dist/lab/parse/subject.js +2 -1
  152. package/dist/lab/parse/values.d.ts +0 -1
  153. package/dist/lab/parse/values.js +0 -3
  154. package/dist/lab/persona-resolve.d.ts +3 -3
  155. package/dist/lab/persona-resolve.js +4 -4
  156. package/dist/lab/persona.js +1 -3
  157. package/dist/lab/plan-base.d.ts +6 -2
  158. package/dist/lab/plan-base.js +22 -7
  159. package/dist/lab/plan-participants.d.ts +5 -5
  160. package/dist/lab/plan-participants.js +2 -2
  161. package/dist/lab/plan-types.d.ts +33 -7
  162. package/dist/lab/plan.d.ts +3 -11
  163. package/dist/lab/plan.js +18 -42
  164. package/dist/lab/preflight-result.js +0 -2
  165. package/dist/lab/preflight.d.ts +0 -3
  166. package/dist/lab/preflight.js +1 -1
  167. package/dist/lab/requirements.d.ts +20 -0
  168. package/dist/lab/requirements.js +54 -0
  169. package/dist/lab/route-inputs.d.ts +23 -12
  170. package/dist/lab/route-inputs.js +48 -51
  171. package/dist/lab/routing.d.ts +19 -24
  172. package/dist/lab/routing.js +14 -47
  173. package/dist/lab/run-lab-events.d.ts +6 -11
  174. package/dist/lab/run-lab-events.js +3 -11
  175. package/dist/lab/run-lab-homes.d.ts +64 -0
  176. package/dist/lab/run-lab-homes.js +3 -0
  177. package/dist/lab/run-lab-options.d.ts +12 -66
  178. package/dist/lab/run-lab-options.js +45 -275
  179. package/dist/lab/summary.d.ts +9 -4
  180. package/dist/lab/summary.js +15 -8
  181. package/dist/lab/types.d.ts +132 -132
  182. package/dist/lab/validation.d.ts +15 -15
  183. package/dist/lab/validation.js +28 -28
  184. package/dist/lab/warnings.js +20 -19
  185. package/dist/observer/artifact.d.ts +1 -1
  186. package/dist/observer/artifact.js +3 -3
  187. package/dist/observer/data.js +2 -2
  188. package/dist/observer/render.js +2 -2
  189. package/dist/observer/run-routes.d.ts +1 -1
  190. package/dist/observer/run-routes.js +5 -5
  191. package/dist/observer/serve.d.ts +17 -0
  192. package/dist/observer/serve.js +34 -3
  193. package/dist/observer-app.html +1 -1
  194. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  195. package/dist/routes/computer-use/bundle-parts.js +10 -3
  196. package/dist/routes/computer-use/bundle.d.ts +4 -11
  197. package/dist/routes/computer-use/bundle.js +9 -15
  198. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  199. package/dist/routes/computer-use/diagnostics.js +1 -1
  200. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  201. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  202. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  203. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  204. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  205. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  206. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  207. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  208. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  209. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  210. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  211. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  212. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  213. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  214. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  215. package/dist/routes/computer-use/external-comms.js +19 -43
  216. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  217. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  218. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  219. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  220. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  221. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  222. package/dist/routes/computer-use/live-flush.js +19 -27
  223. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +14 -13
  224. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  225. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  226. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  227. package/dist/routes/computer-use/local-vm.js +39 -66
  228. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  229. package/dist/routes/computer-use/participant-desktop.js +5 -25
  230. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  231. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  232. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  233. package/dist/routes/computer-use/participant-facts.js +12 -1
  234. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  235. package/dist/routes/computer-use/participant-model.js +58 -33
  236. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  237. package/dist/routes/computer-use/participant-prompt.js +4 -4
  238. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  239. package/dist/routes/computer-use/participant-runs.js +8 -8
  240. package/dist/routes/computer-use/plan.d.ts +21 -29
  241. package/dist/routes/computer-use/plan.js +59 -65
  242. package/dist/routes/computer-use/preflight.d.ts +6 -11
  243. package/dist/routes/computer-use/preflight.js +26 -18
  244. package/dist/routes/computer-use/rerun-selection.js +10 -6
  245. package/dist/routes/computer-use/result.d.ts +1 -1
  246. package/dist/routes/computer-use/result.js +40 -30
  247. package/dist/routes/computer-use/route.d.ts +3 -4
  248. package/dist/routes/computer-use/route.js +21 -19
  249. package/dist/routes/computer-use/self-report.d.ts +2 -2
  250. package/dist/routes/computer-use/self-report.js +4 -4
  251. package/dist/routes/computer-use/setup.d.ts +8 -17
  252. package/dist/routes/computer-use/setup.js +98 -86
  253. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  254. package/dist/routes/computer-use/single-bundle.js +20 -25
  255. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  256. package/dist/routes/computer-use/subject-projection.js +20 -19
  257. package/dist/routes/computer-use/types.d.ts +169 -211
  258. package/dist/routes/computer-use/types.js +13 -6
  259. package/dist/routes/preview.js +0 -1
  260. package/dist/routes/scripted/bundle.d.ts +3 -6
  261. package/dist/routes/scripted/bundle.js +11 -16
  262. package/dist/routes/scripted/plan.d.ts +5 -7
  263. package/dist/routes/scripted/plan.js +6 -4
  264. package/dist/routes/scripted/result.d.ts +4 -1
  265. package/dist/routes/scripted/result.js +10 -6
  266. package/dist/routes/scripted/route.js +10 -11
  267. package/dist/routes/scripted/scenario.d.ts +1 -1
  268. package/dist/routes/scripted/scenario.js +1 -1
  269. package/dist/routes/scripted/setup.d.ts +3 -2
  270. package/dist/routes/scripted/setup.js +22 -21
  271. package/dist/routes/scripted/subject.d.ts +8 -3
  272. package/dist/routes/scripted/subject.js +11 -6
  273. package/dist/routes/scripted/surface-records.js +1 -1
  274. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  275. package/dist/routes/scripted/surface-sessions.js +4 -4
  276. package/dist/routes/scripted/types.d.ts +19 -36
  277. package/dist/routes/scripted/types.js +1 -2
  278. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  279. package/dist/routes/shared-world/bundle.d.ts +2 -2
  280. package/dist/routes/shared-world/bundle.js +22 -26
  281. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  282. package/dist/routes/shared-world/checkpoints.js +4 -4
  283. package/dist/routes/shared-world/comms.d.ts +5 -4
  284. package/dist/routes/shared-world/comms.js +28 -41
  285. package/dist/routes/shared-world/external-public.d.ts +5 -5
  286. package/dist/routes/shared-world/external-public.js +19 -20
  287. package/dist/routes/shared-world/handoff.d.ts +4 -4
  288. package/dist/routes/shared-world/handoff.js +50 -50
  289. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  290. package/dist/routes/shared-world/lobby-code.js +13 -13
  291. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  292. package/dist/routes/shared-world/{seats.js → participant-specs.js} +46 -51
  293. package/dist/routes/shared-world/plan.d.ts +2 -6
  294. package/dist/routes/shared-world/plan.js +1 -2
  295. package/dist/routes/shared-world/provenance.d.ts +4 -4
  296. package/dist/routes/shared-world/provenance.js +4 -4
  297. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  298. package/dist/routes/shared-world/provisioned.js +48 -41
  299. package/dist/routes/shared-world/result.js +31 -19
  300. package/dist/routes/shared-world/route.js +37 -41
  301. package/dist/routes/shared-world/setup.d.ts +5 -4
  302. package/dist/routes/shared-world/setup.js +12 -14
  303. package/dist/routes/shared-world/types.d.ts +53 -126
  304. package/dist/routes/shared-world/types.js +2 -2
  305. package/dist/routes/terminal/adapter.d.ts +8 -8
  306. package/dist/routes/terminal/adapter.js +28 -125
  307. package/dist/routes/terminal/bundle.d.ts +7 -12
  308. package/dist/routes/terminal/bundle.js +24 -34
  309. package/dist/routes/terminal/credentials.d.ts +2 -2
  310. package/dist/routes/terminal/credentials.js +16 -16
  311. package/dist/routes/terminal/dry-run.d.ts +1 -1
  312. package/dist/routes/terminal/dry-run.js +9 -11
  313. package/dist/routes/terminal/encoding.d.ts +1 -1
  314. package/dist/routes/terminal/encoding.js +2 -2
  315. package/dist/routes/terminal/ledger.d.ts +6 -6
  316. package/dist/routes/terminal/ledger.js +9 -9
  317. package/dist/routes/terminal/live-finish.d.ts +1 -2
  318. package/dist/routes/terminal/live-finish.js +21 -20
  319. package/dist/routes/terminal/live-sandbox.d.ts +4 -2
  320. package/dist/routes/terminal/live-sandbox.js +25 -21
  321. package/dist/routes/terminal/participant-text.d.ts +23 -0
  322. package/dist/routes/terminal/participant-text.js +165 -0
  323. package/dist/routes/terminal/plan.d.ts +2 -6
  324. package/dist/routes/terminal/plan.js +13 -9
  325. package/dist/routes/terminal/recorder.d.ts +6 -1
  326. package/dist/routes/terminal/recorder.js +12 -4
  327. package/dist/routes/terminal/result.js +4 -4
  328. package/dist/routes/terminal/route.js +26 -26
  329. package/dist/routes/terminal/runtime.d.ts +3 -2
  330. package/dist/routes/terminal/runtime.js +3 -3
  331. package/dist/routes/terminal/sandbox.d.ts +5 -3
  332. package/dist/routes/terminal/sandbox.js +13 -16
  333. package/dist/routes/terminal/session.js +16 -14
  334. package/dist/routes/terminal/token-usage.js +5 -5
  335. package/dist/routes/terminal/trace.d.ts +5 -8
  336. package/dist/routes/terminal/trace.js +9 -64
  337. package/dist/routes/terminal/types.d.ts +85 -93
  338. package/dist/routes/terminal/types.js +9 -4
  339. package/dist/run/active-runs.d.ts +13 -0
  340. package/dist/run/active-runs.js +12 -0
  341. package/dist/run/bundle-shape.d.ts +2 -1
  342. package/dist/run/bundle-shape.js +4 -4
  343. package/dist/run/bundle.d.ts +63 -56
  344. package/dist/run/bundle.js +9 -8
  345. package/dist/run/cost-summary.js +3 -2
  346. package/dist/run/costs.d.ts +6 -6
  347. package/dist/run/costs.js +10 -10
  348. package/dist/run/detail.d.ts +5 -5
  349. package/dist/run/detail.js +6 -6
  350. package/dist/run/dry-run.js +5 -12
  351. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  352. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  353. package/dist/run/feedback-shape.js +1 -1
  354. package/dist/run/judge.d.ts +16 -4
  355. package/dist/run/judge.js +24 -7
  356. package/dist/run/locate.d.ts +2 -0
  357. package/dist/run/locate.js +3 -1
  358. package/dist/run/outcomes.d.ts +3 -3
  359. package/dist/run/outcomes.js +3 -3
  360. package/dist/run/participant-records.d.ts +2 -2
  361. package/dist/run/participant-records.js +2 -2
  362. package/dist/run/paths.js +1 -1
  363. package/dist/run/pricing.d.ts +19 -9
  364. package/dist/run/pricing.js +30 -18
  365. package/dist/run/projection.d.ts +13 -13
  366. package/dist/run/projection.js +8 -8
  367. package/dist/run/reclaim.d.ts +7 -1
  368. package/dist/run/reclaim.js +24 -4
  369. package/dist/run/results.d.ts +1 -1
  370. package/dist/run/run-index.d.ts +1 -1
  371. package/dist/run/run-index.js +11 -11
  372. package/dist/run/run.d.ts +4 -2
  373. package/dist/run/run.js +9 -5
  374. package/dist/run/sandbox-receipts.d.ts +4 -4
  375. package/dist/run/sandbox-receipts.js +4 -4
  376. package/dist/run/shared-world-evidence.d.ts +47 -47
  377. package/dist/run/shared-world-shape.d.ts +3 -3
  378. package/dist/run/shared-world-shape.js +11 -11
  379. package/dist/run/stats.d.ts +5 -5
  380. package/dist/run/stats.js +8 -8
  381. package/dist/run/status.d.ts +16 -6
  382. package/dist/run/status.js +31 -8
  383. package/dist/run/streams.d.ts +26 -19
  384. package/dist/run/terminal-contract.d.ts +5 -5
  385. package/dist/run/terminal-contract.js +4 -4
  386. package/dist/run/transient-comms-secrets.d.ts +5 -0
  387. package/dist/run/transient-comms-secrets.js +12 -0
  388. package/dist/run-lab.d.ts +36 -34
  389. package/dist/run-lab.js +41 -37
  390. package/dist/subject/desktop-cli.d.ts +1 -1
  391. package/dist/subject/desktop-cli.js +1 -1
  392. package/dist/subject/local-tree-archive.d.ts +1 -1
  393. package/dist/subject/local-tree-archive.js +4 -4
  394. package/dist/subject/local-tree.d.ts +2 -2
  395. package/dist/subject/local-tree.js +1 -1
  396. package/dist/subject/node-bootstrap.d.ts +1 -1
  397. package/dist/subject/node-bootstrap.js +4 -4
  398. package/dist/subject/runtime.js +5 -5
  399. package/dist/subject/serve.js +1 -1
  400. package/dist/subject/steps.d.ts +4 -4
  401. package/dist/subject/steps.js +5 -5
  402. package/dist/substrates/desktop-session.d.ts +2 -0
  403. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  404. package/dist/substrates/e2b/cdp-probe.js +1 -1
  405. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  406. package/dist/substrates/e2b/desktop-browser.js +4 -4
  407. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  408. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  409. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  410. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  411. package/dist/substrates/e2b/desktop-media.js +2 -2
  412. package/dist/substrates/e2b/sandbox.d.ts +2 -0
  413. package/dist/substrates/e2b/sandbox.js +22 -8
  414. package/dist/substrates/e2b/sdk.d.ts +12 -1
  415. package/dist/substrates/e2b/sdk.js +30 -9
  416. package/dist/substrates/local/runtime-host.d.ts +2 -0
  417. package/dist/substrates/local/runtime-host.js +6 -0
  418. package/dist/tui/actions.d.ts +7 -5
  419. package/dist/tui/actions.js +18 -9
  420. package/dist/tui-app.js +42 -42
  421. package/dist/verify/actor.d.ts +10 -10
  422. package/dist/verify/actor.js +15 -15
  423. package/dist/verify/artifacts.d.ts +1 -1
  424. package/dist/verify/artifacts.js +3 -3
  425. package/dist/verify/costs.d.ts +2 -2
  426. package/dist/verify/costs.js +2 -2
  427. package/dist/verify/liveness.d.ts +1 -1
  428. package/dist/verify/liveness.js +4 -1
  429. package/dist/verify/rerun.d.ts +1 -1
  430. package/dist/verify/rerun.js +1 -1
  431. package/dist/verify/shared-world.js +2 -2
  432. package/dist/verify/verify.js +6 -6
  433. package/docs/README.md +1 -1
  434. package/docs/architecture/actor-contract.md +60 -22
  435. package/docs/architecture/desktop-sessions.md +9 -9
  436. package/docs/architecture/external-public-shared-world.md +5 -0
  437. package/docs/architecture/observer.md +4 -4
  438. package/docs/architecture/restricted-codex-analysis.md +40 -4
  439. package/docs/architecture/state-driven-executor.md +4 -5
  440. package/docs/architecture/task-protocol-support.md +3 -5
  441. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  442. package/docs/contracts/run-bundle.md +10 -8
  443. package/docs/contracts/schemas.md +109 -53
  444. package/docs/contracts/study-analysis.md +24 -0
  445. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  446. package/docs/product/automatic-analysis.md +1 -0
  447. package/docs/ramp/README.md +2 -1
  448. package/package.json +4 -4
  449. package/skills/humanish/SKILL.md +3 -2
  450. package/skills/humanish/agents/openai.yaml +1 -1
  451. package/dist/deprecated.d.ts +0 -90
  452. package/dist/deprecated.js +0 -106
  453. package/dist/lab/bag-overrides.d.ts +0 -18
  454. package/dist/lab/bag-overrides.js +0 -121
  455. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  456. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  457. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  458. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  459. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -6,8 +6,8 @@ export declare const LAB_CONFIG_SCHEMA = "humanish.lab.v2";
6
6
  export declare const ID_PATTERN: RegExp;
7
7
  /**
8
8
  * Where the run acts: the host repo, a fresh clone, a running app a browser actor drives
9
- * (`app-url`), an already-running LOCAL dev server driven IN-PROCESS via a custom
10
- * CuaExecutor with NO clone and NO E2B desktop (`local-app`), or the operator's own local
9
+ * (`app-url`), an already-running local dev server driven in-process via a custom
10
+ * CuaExecutor with no clone and no E2B desktop (`local-app`), or the operator's own local
11
11
  * working tree packed and provisioned in-sandbox in place of a clone (`local-tree`).
12
12
  * `local-app` routes to the cua backend and is library-assisted: a caller supplies
13
13
  * `RunLabOptions.inProcess` + `createProvider` (no built-in driver exists yet), and the engine
@@ -16,11 +16,11 @@ export declare const ID_PATTERN: RegExp;
16
16
  */
17
17
  type LabSubjectSource = "this-repo" | "clone" | "app-url" | "local-app" | "terminal-product" | "desktop-cli" | "local-tree";
18
18
  /**
19
- * How a subject's WORLD relates across actor lanes. `per-lane-worlds` (the default; absent ==
20
- * this) is the only fan-out topology the computer-use route ships — N lanes, N independent
21
- * worlds, isolation + per-lane attribution. `shared-world` (#164) is the DECLARED override: ONE
22
- * mutable service plane that N role SEATS use at the same time, so their actions interact through
23
- * shared state. Consumed ONLY on the shared-world routes (a provisioned clone plane, or an
19
+ * How a subject's world relates across participants. `per-lane-worlds` (the default; absent ==
20
+ * this) is the only fan-out topology the computer-use route ships — N participants, N independent
21
+ * worlds, isolation + per-participant attribution. `shared-world` (#164) is the declared override: one
22
+ * mutable service plane that N participants use at the same time, so their actions interact through
23
+ * shared state. Consumed only on the shared-world routes (a provisioned clone plane, or an
24
24
  * external-public app-url plane) with a computer-use actor; inert/warned everywhere else
25
25
  * (invariant 6).
26
26
  */
@@ -28,7 +28,7 @@ type LabSubjectTopology = "per-lane-worlds" | "shared-world";
28
28
  export interface LabSubjectClone {
29
29
  /** git clone depth; 1 (shallow) by default. Consumed on the computer-use clone route. */
30
30
  depth?: number;
31
- /** how many independent clone lanes to fan out (one sandbox/desktop each). */
31
+ /** how many participants to fan out, each with its own clone (one sandbox/desktop each). */
32
32
  fanout?: number;
33
33
  /** keep the disposable clone for debugging instead of discarding. */
34
34
  keep?: boolean;
@@ -54,7 +54,7 @@ export interface LabSubjectServe {
54
54
  /** Required long-lived start command — launched detached; the sandbox lifecycle owns it. */
55
55
  start: string;
56
56
  /** Loopback entry URL: the readiness-probe target and the URL the actor drives. The lab
57
- * serves the clone INSIDE the sandbox, so this is always loopback (not subject to
57
+ * serves the clone inside the sandbox, so this is always loopback (not subject to
58
58
  * allowPublicTargets — that governs app-url subjects, i.e. external deployments). */
59
59
  url: string;
60
60
  /** Budget for the served app to answer the readiness probe. Default 180000. */
@@ -70,38 +70,38 @@ interface LabSubjectStateStep {
70
70
  /**
71
71
  * [a-z0-9-] step label (must start alphanumeric), <=40 chars, unique across steps; becomes
72
72
  * the detached-step name `subject-state-<name>` (interpolates into in-sandbox file paths —
73
- * the shape is load-bearing, validated at parse AND re-enforced in the engine).
73
+ * the shape is load-bearing, validated at parse and re-enforced in the engine).
74
74
  */
75
75
  name: string;
76
76
  /**
77
77
  * Author-trusted shell command (same trust class as serve.install/build/start — the
78
78
  * "serve commands are author-trusted" corollary). Runs detached in the subject directory
79
79
  * with an atomic status file, kill-on-timeout, and a capped log tail. Persisted in
80
- * evidence as a sha256-16 DIGEST only, never as text.
80
+ * evidence as a sha256-16 digest only, never as text.
81
81
  */
82
82
  command: string;
83
83
  /**
84
84
  * Phase: before-build (after install — for builds that read the DB, e.g. SSG),
85
85
  * before-start (after build, before the server launches — migrations, SQL/file fixtures,
86
86
  * an in-sandbox `service postgresql start`), after-ready (after the readiness probe —
87
- * fixtures loaded through the RUNNING app's API). Default: before-start.
87
+ * fixtures loaded through the running app's API). Default: before-start.
88
88
  */
89
89
  when?: LabStateStepWhen;
90
90
  /** Wall-clock budget per step. Default 300000. */
91
91
  timeoutMs?: number;
92
92
  }
93
93
  /**
94
- * A shared-world state CHECKPOINT: an author-trusted, READ-ONLY, AGGREGATE/DIGEST probe command
94
+ * A shared-world state checkpoint: an author-trusted, read-only, aggregate/digest probe command
95
95
  * (counts, max-timestamps, hashes) run at baseline and after each role's turn. Reuses the
96
96
  * seed-step validation shape (name [a-z0-9-] ≤40, unique; command required). Persisted DIGEST-ONLY
97
97
  * (only sha256-16(scrub+redact(stdout)) ever lands — never the raw value), same lockdown as the
98
- * seed surface. Consumed ONLY on the shared-world route (#164); inert/warned elsewhere.
98
+ * seed surface. Consumed only on the shared-world route (#164); inert/warned elsewhere.
99
99
  */
100
100
  export interface LabSubjectStateCheckpoint {
101
101
  /**
102
102
  * [a-z0-9-] probe label (must start alphanumeric), <=40 chars, unique across checkpoints;
103
103
  * names the detached step (`checkpoint-<snapshot>-<name>`) — load-bearing shape, validated at
104
- * parse AND re-enforced in the engine.
104
+ * parse and re-enforced in the engine.
105
105
  */
106
106
  name: string;
107
107
  /**
@@ -113,39 +113,39 @@ export interface LabSubjectStateCheckpoint {
113
113
  /**
114
114
  * Optional extra literal values to scrub from this probe's stdout before digesting (author-known
115
115
  * values that may appear in the probe output, beyond the harness-provisioned env values which are
116
- * always scrubbed). Names/values are NEVER persisted — only the digest is.
116
+ * always scrubbed). Names and values are never persisted; only the digest is.
117
117
  */
118
118
  redact?: string[];
119
119
  }
120
- /** The subject's STATE story (clone subjects): seeded in-sandbox, or declared external. */
120
+ /** The subject's state story (clone subjects): seeded in-sandbox, or declared external. */
121
121
  export interface LabSubjectState {
122
122
  /** Ordered seed/migration/fixture steps. Order within a phase is declaration order. */
123
123
  seed?: LabSubjectStateStep[];
124
124
  /**
125
- * Env var NAMES whose values point at state the lab does NOT control (e.g. a shared dev
125
+ * Env var names whose values point at state the lab does not control (e.g. a shared dev
126
126
  * DB). Must be a subset of subject.env (so the declaration is mechanically backed by a
127
127
  * provisioned name, not a vibe). Flips state provenance to "unpinned".
128
128
  */
129
129
  external?: string[];
130
130
  /**
131
131
  * Shared-world state checkpoints (#164): read-only digest probes run at baseline + after each
132
- * role's turn to produce the harness-clocked interaction timeline. Consumed ONLY on the
132
+ * role's turn to produce the harness-clocked interaction timeline. Consumed only on the
133
133
  * shared-world route; inert/warned elsewhere (invariant 6). Shape-validated everywhere.
134
134
  */
135
135
  checkpoint?: LabSubjectStateCheckpoint[];
136
136
  }
137
137
  /**
138
- * `terminal-product`: the product-under-study a terminal agent must discover and use from PUBLIC
139
- * SURFACES ONLY (the terminal-product route's subject). The subject is NOT provisioned/cloned —
140
- * the agent drives the declared public surfaces, so provenance is UNPINNED (invariant 5). The
141
- * concrete product name + surfaces are operator data; committed fixtures use a NEUTRAL mock name.
138
+ * `terminal-product`: the product-under-study a terminal agent must discover and use from public
139
+ * surfaces only (the terminal-product route's subject). The subject is not provisioned or cloned:
140
+ * the agent drives the declared public surfaces, so provenance is unpinned (invariant 5). The
141
+ * concrete product name + surfaces are operator data; committed fixtures use a neutral mock name.
142
142
  */
143
143
  export interface LabSubjectProduct {
144
144
  /** Public-safe product label (shape-validated like a lab id; interpolates into evidence). */
145
145
  name: string;
146
146
  /**
147
- * How the product gets onto the machine, run UNKEYED before the participant starts, in the
148
- * lane's working directory. Consumed on BOTH product routes: `desktop-cli` (a person at a
147
+ * How the product gets onto the machine, run with no keys before the participant starts, in the
148
+ * participant's working directory. Consumed on both product routes: `desktop-cli` (a person at a
149
149
  * desktop) and `terminal-product` (an agent in a shell).
150
150
  *
151
151
  * Absent means the participant installs it themselves from the public surfaces, which is a
@@ -157,28 +157,28 @@ export interface LabSubjectProduct {
157
157
  */
158
158
  install?: string;
159
159
  /**
160
- * `desktop-cli` ONLY: the directory the participant's terminal opens in. Absent means the home
161
- * directory. (The terminal-product lane has its own fixed study workdir.)
160
+ * `desktop-cli` only: the directory the participant's terminal opens in. Absent means the home
161
+ * directory. (The terminal-product route has its own fixed study workdir.)
162
162
  *
163
163
  * This exists because the first live study failed on it: the participant was asked what studies
164
164
  * the project contained, landed in an empty home directory, correctly reported that there was no
165
165
  * project, and stopped. The finding was about the lab, not the product. A study of a
166
- * project-scoped tool has to put the participant IN a project, the same way an app study opens
166
+ * project-scoped tool has to put the participant inside a project, the same way an app study opens
167
167
  * the app rather than a blank tab.
168
168
  */
169
169
  workdir?: string;
170
170
  /**
171
- * The product's PUBLIC surfaces — the only world the agent sees. Each must be an http(s) URL
171
+ * The product's public surfaces, the only world the agent sees. Each must be an http(s) URL
172
172
  * (e.g. a docs page, an llms.txt, a skill manifest). Validated at parse; recorded in evidence.
173
173
  */
174
174
  publicSurfaces: string[];
175
175
  /**
176
- * `terminal-product` ONLY: a local file uploaded into the sandbox before `install` runs, and
176
+ * `terminal-product` only: a local file uploaded into the sandbox before `install` runs, and
177
177
  * exposed to it as `$HUMANISH_PRODUCT_UPLOAD`. A project-relative path; `..` and absolute paths
178
178
  * are refused, because this reads a file off the operator's disk and puts it on a machine an
179
179
  * autonomous agent is about to drive.
180
180
  *
181
- * It exists so a study can test a build that is NOT PUBLISHED YET. Installing `@latest` measures
181
+ * It exists so a study can test a build that is not published yet. Installing `@latest` measures
182
182
  * the last release, which is exactly the wrong artifact for a pre-release gate — the point is to
183
183
  * meet the candidate before anyone else does. Any adopter shipping a CLI wants the same thing.
184
184
  */
@@ -187,31 +187,31 @@ export interface LabSubjectProduct {
187
187
  export interface LabSubject {
188
188
  source: LabSubjectSource;
189
189
  /**
190
- * WORLD topology across actor lanes. Absent == `per-lane-worlds` (the isolation default; every
190
+ * World topology across participants. Absent == `per-lane-worlds` (the isolation default; every
191
191
  * existing lab is byte-stable). `shared-world` is the declared override (#164): one mutable
192
- * service plane, N role seats at once. Consumed ONLY on the shared-world routes (a provisioned
193
- * clone or an external-public app-url plane, a computer-use actor, and a roster of ≥2 lanes);
192
+ * service plane, N role seats at once. Consumed only on the shared-world routes (a provisioned
193
+ * clone or an external-public app-url plane, a computer-use actor, and a roster of ≥2 participants);
194
194
  * inert/warned elsewhere.
195
195
  */
196
196
  topology?: LabSubjectTopology;
197
197
  /**
198
- * CONCURRENT shared-world route ONLY (#164 phase 2): the author's REQUIRED attestation that the
199
- * subject behind the internet-reachable `getHost` URL is SYNTHETIC seeded data. The concurrent
198
+ * Concurrent shared-world route only (#164 phase 2): the author's required attestation that the
199
+ * subject behind the internet-reachable `getHost` URL is synthetic seeded data. The concurrent
200
200
  * route exposes the subject on a tokenless public URL for the run's duration, so real/external
201
201
  * data must never sit behind it. This is author-trust + a provenance gate (verify also requires
202
- * `subject.state.provenance == "seeded"`), NOT a no-real-data guarantee. Required when
202
+ * `subject.state.provenance == "seeded"`). It does not guarantee the data is synthetic. Required when
203
203
  * `topology: shared-world` + `execution.concurrency > 1`; inert/warned elsewhere.
204
204
  */
205
205
  exposure?: "synthetic";
206
206
  /**
207
- * EXTERNAL-PUBLIC shared-world route ONLY (#164 phase 2): the author's REQUIRED ownership
208
- * attestation when a real PUBLIC deployment (`source: app-url` + `topology: shared-world` +
207
+ * External-public shared-world route only (#164 phase 2): the author's required ownership
208
+ * attestation when a real public deployment (`source: app-url` + `topology: shared-world` +
209
209
  * `concurrency > 1` + `policies.allowPublicTargets: true`) is used directly as the shared plane.
210
210
  * The harness neither provisions nor exposes this target (no getHost, no clone, no seed), so it
211
- * cannot attest the data is synthetic; instead the operator MUST attest they own/operate it.
211
+ * cannot attest the data is synthetic; instead the operator must attest they own/operate it.
212
212
  * `owner` is a public-safe operator/repo label; `authorized` must be true. This is author-trust —
213
213
  * the harness cannot verify ownership — surfaced honestly in the evidence class. Required on the
214
- * external-public branch. On a non-`app-url` subject it is REJECTED (parse error); on any OTHER
214
+ * external-public branch. On a non-`app-url` subject it is rejected (parse error); on any other
215
215
  * `app-url` config that does not route to external-public shared-world it is IGNORED-WITH-A-WARNING
216
216
  * (forwardDeclaredWarnings), never silently consumed — it is meaningless without that plane.
217
217
  */
@@ -225,29 +225,29 @@ export interface LabSubject {
225
225
  /**
226
226
  * `app-url`: a loopback http(s) URL the computer-use actor drives (127.0.0.1/localhost
227
227
  * only — driving arbitrary public sites is not allowed). The URL must be reachable from
228
- * INSIDE the desktop sandbox; library callers provision it via the prepareDesktop hook.
228
+ * inside the desktop sandbox; library callers provision it via the prepareDesktop hook.
229
229
  * For a config-only path use `clone` + `serve` — the lab serves the app itself.
230
230
  *
231
- * `local-app`: the loopback http(s) URL of an already-running LOCAL dev server the caller's
231
+ * `local-app`: the loopback http(s) URL of an already-running local dev server the caller's
232
232
  * custom CuaExecutor drives in-process (no sandbox, no public-target option — always
233
- * loopback). Passed to `buildExecutor` so the bridge knows where the app lives.
233
+ * loopback). Passed to `inProcess.executor` so the bridge knows where the app lives.
234
234
  */
235
235
  appUrl?: string;
236
236
  /** `clone` (computer-use route): how the cloned app is served in-sandbox. */
237
237
  serve?: LabSubjectServe;
238
238
  /**
239
- * Env var NAMES the subject app needs, provisioned into the sandbox from the caller's
239
+ * Env var names the subject app needs, provisioned into the sandbox from the caller's
240
240
  * environment (--env-file). Names are recorded in evidence; values never are. Consumed
241
241
  * on the computer-use clone route.
242
242
  */
243
243
  env?: string[];
244
244
  /**
245
- * LITERAL, NON-SECRET env values committed alongside the lab — the configuration every real app
245
+ * Literal, non-secret env values committed alongside the lab: the configuration every real app
246
246
  * needs before it will boot: a public base URL, a transport selector, a feature flag. None of that
247
247
  * is secret, and routing it through `subject.env` would force an adopter to carry a private env
248
248
  * file just to reproduce a public study, which is the opposite of a reproducible lab.
249
249
  *
250
- * These values ARE recorded in evidence, because they are part of how the subject was configured,
250
+ * These values are recorded in evidence, because they are part of how the subject was configured,
251
251
  * so a value that looks like a secret or a local path is refused at parse rather than committed to
252
252
  * a public repo. Anything genuinely secret belongs in `subject.env`.
253
253
  */
@@ -256,12 +256,12 @@ export interface LabSubject {
256
256
  * `clone` (computer-use route): the subject's state story — seed/migration/fixture steps
257
257
  * executed in-sandbox around the serve sequence, and/or declared external state. Recorded
258
258
  * in the run bundle as structured provenance (invariant 5): seeded with command digests,
259
- * UNPINNED for external state, declared-not-run for dry-run/failed provisioning.
259
+ * unpinned for external state, declared-not-run for dry-run/failed provisioning.
260
260
  */
261
261
  state?: LabSubjectState;
262
262
  /**
263
263
  * `terminal-product` (terminal route): the product the terminal agent discovers + uses from
264
- * PUBLIC surfaces only. Consumed on the terminal route; rejected on every other source.
264
+ * public surfaces only. Consumed on the terminal route; rejected on every other source.
265
265
  */
266
266
  product?: LabSubjectProduct;
267
267
  /**
@@ -276,98 +276,98 @@ export interface LabSubject {
276
276
  export interface LabParticipantFocus {
277
277
  id?: string;
278
278
  label?: string;
279
- /** Per-lane steer appended to the actor's mission. Consumed on the app-url route. */
279
+ /** Per-participant steer appended to the actor's mission. Consumed on the app-url route. */
280
280
  instruction?: string;
281
281
  }
282
282
  /**
283
- * One differentiated fan-out lane on the computer-use E2B route (per-lane worlds). Each lane
284
- * becomes an independent E2B desktop sandbox with its own persona/device/starting-steer. All
283
+ * One participant in a differentiated fan-out on the computer-use E2B route (`per-lane-worlds`).
284
+ * Each entry becomes an independent E2B desktop sandbox with its own persona/device/starting-steer. All
285
285
  * fields optional: an omitted persona/device/instruction inherits the actor-level default. `id`
286
- * defaults to `lane-01`..`lane-NN` and must be a public-safe token (it names per-lane evidence
287
- * paths). Consumed ONLY on the computer-use E2B route (inert/warned elsewhere).
286
+ * defaults to `lane-01`..`lane-NN` and must be a public-safe token (it names per-participant evidence
287
+ * paths). Consumed only on the computer-use E2B route (inert/warned elsewhere).
288
288
  */
289
289
  export interface LabParticipantEntry {
290
- /** Public-safe lane label (interpolates into per-lane evidence paths). Default lane-NN. */
290
+ /** Public-safe participant id (interpolates into its evidence paths). Default lane-NN. */
291
291
  id?: string;
292
292
  /**
293
293
  * App-defined actor type label for grouping simulated users ("operator", "viewer",
294
- * "maintainer", etc.). This is NOT the execution actor dispatch key (`actors[0].type`);
294
+ * "maintainer", etc.). It is separate from the execution actor dispatch key (`actors[0].type`);
295
295
  * it is adapter-owned taxonomy for roster/readback.
296
296
  */
297
297
  actorType?: string;
298
- /** App-defined surface label for grouping lanes that start from different product areas. */
298
+ /** App-defined surface label for grouping participants that start from different product areas. */
299
299
  surface?: string;
300
- /** App-defined correlation id tying lanes to one shared case/account/work item. */
300
+ /** App-defined correlation id tying participants to one shared case/account/work item. */
301
301
  caseGroup?: string;
302
- /** Persona id/label threaded into this lane's actor prompt. Default: actors[0].persona. */
302
+ /** Persona id/label threaded into this participant's actor prompt. Default: actors[0].persona. */
303
303
  persona?: string;
304
- /** Named hosted-screen preset for this lane. XOR raw execution.desktop.resolution. */
304
+ /** Named hosted-screen preset for this participant. XOR raw execution.desktop.resolution. */
305
305
  device?: string;
306
- /** Per-lane steer appended to this lane's mission (the roster's per-lane focus). */
306
+ /** Steer appended to this participant's mission (the roster's per-participant focus). */
307
307
  instruction?: string;
308
308
  /**
309
- * Deterministic lane completion guard. When set, this lane stops as soon as the runtime
309
+ * Deterministic participant completion guard. When set, this participant stops as soon as the runtime
310
310
  * observation matches any declared rule; actor-level stopWhen is used as the default.
311
311
  */
312
312
  stopWhen?: StopWhen;
313
- /** A declared observation window for THIS lane (#510); actor-level dwell is the default. */
313
+ /** A declared observation window for this participant (#510); actor-level dwell is the default. */
314
314
  dwell?: DwellWindow;
315
315
  /**
316
- * How hard the model is asked to think in THIS lane; actor-level reasoningEffort is the default.
316
+ * How hard the model is asked to think for this participant; actor-level reasoningEffort is the default.
317
317
  *
318
318
  * The single-run control: same persona, same mission, two efforts, one set of conditions.
319
319
  */
320
320
  reasoningEffort?: ReasoningEffort;
321
321
  /**
322
- * App-url computer-use ONLY: absolute browser URL this lane opens instead of `subject.appUrl`.
322
+ * App-url computer-use only: absolute browser URL this participant opens instead of `subject.appUrl`.
323
323
  * This is the generic setup-produced-target handoff for crawler/swarm labs: product adapters may
324
- * start any topology they need, then hand humanish explicit lane targets. Public/non-loopback
324
+ * start any topology they need, then hand humanish explicit participant targets. Public/non-loopback
325
325
  * targets still require `policies.allowPublicTargets: true`. Inert/rejected on clone, local-app,
326
326
  * shared-world, scripted-browser, and terminal routes.
327
327
  */
328
328
  target?: string;
329
329
  /**
330
- * Shared-world ONLY (#164): this role's per-seat loopback entry route, resolved against
331
- * `subject.serve.url` and REQUIRED to be same-origin (loopback) with it — the seat opens
332
- * `serve.url + entry`. Validated at parse AND re-enforced in the engine. Inert/warned on every
333
- * non-shared-world route (the per-lane-worlds fan-out roster has no per-lane entry).
330
+ * Shared-world only (#164): this participant's loopback entry route, resolved against
331
+ * `subject.serve.url`. It must be same-origin (loopback) with it, and the participant opens
332
+ * `serve.url + entry`. Validated at parse and re-enforced in the engine. Inert/warned on every
333
+ * non-shared-world route (the per-lane-worlds fan-out roster has no per-participant entry).
334
334
  */
335
335
  entry?: string;
336
336
  /**
337
- * EXTERNAL-PUBLIC shared-world ONLY (#164 phase 2): marks this lane the DESIGNATED HOST seat — it
337
+ * External-public shared-world only (#164 phase 2): marks this participant as the host. It
338
338
  * creates the shared session (e.g. a multiplayer lobby) that the follower seats then join. Exactly
339
- * ONE lane in the roster may carry `host: true` (validated in externalPublicSharedWorldValidationReason).
339
+ * one participant in the roster may carry `host: true` (validated in externalPublicSharedWorldValidationReason).
340
340
  * The orchestrator watches the host seat's observed URL for the shared-session code and threads it
341
341
  * into the follower missions at a host-first barrier. Inert/warned on every other route.
342
342
  */
343
343
  host?: boolean;
344
344
  }
345
345
  /**
346
- * Compact authoring sugar for repeated lane groups. The parser expands each group into concrete
346
+ * Compact authoring sugar for repeated participant groups. The parser expands each group into concrete
347
347
  * `lanes[]` with deterministic ids (`<group.id>-01`, `<group.id>-02`, ...). The runtime never
348
348
  * consumes this shape directly; it always sees ordinary `LabActorLane` entries.
349
349
  */
350
350
  export interface LabActorRosterGroup extends Omit<LabParticipantEntry, "id"> {
351
- /** Public-safe group id; prefixes generated lane ids. */
351
+ /** Public-safe group id; prefixes generated participant ids. */
352
352
  id: string;
353
- /** Number of lanes to generate for this group. */
353
+ /** Number of participants to generate for this group. */
354
354
  count: number;
355
355
  }
356
356
  export interface LabActor {
357
357
  /**
358
358
  * The actor label. On computer-use (including shared-world), scripted-browser, and
359
- * terminal-product routes this is a REAL dispatch key resolved against the closed first-party
359
+ * terminal-product routes this is a real dispatch key resolved against the closed first-party
360
360
  * actor registry. On the synthetic route it remains a free-form descriptive label (e.g.
361
361
  * synthetic-persona). The terminal route owns its live lifecycle after using
362
362
  * the descriptor for dispatch and capability enforcement.
363
363
  */
364
364
  type: string;
365
- /** Lane count — route-specific (see HONEST SCOPE header): synthetic simCount; scripted
365
+ /** Participant count, route-specific (see the scope header in config.ts): synthetic simCount; scripted
366
366
  * surface roster {1 = desktop, 2 = desktop + mobile, default 1}; computer-use E2B route the
367
- * HOMOGENEOUS fan-out lane count (cap 16). XOR `lanes`. */
367
+ * homogeneous fan-out participant count (cap 16). XOR `lanes`. */
368
368
  count?: number;
369
- /** Computer-use E2B route: a DIFFERENTIATED fan-out roster (per-lane worlds). XOR `count`,
370
- * `roster`, and `laneFocus`. Cap 16 lanes. Consumed only on the cua E2B route
369
+ /** Computer-use E2B route: a differentiated fan-out roster (`per-lane-worlds`). XOR `count`,
370
+ * `roster`, and `laneFocus`. Cap 16 participants. Consumed only on the cua E2B route
371
371
  * (inert/warned elsewhere). */
372
372
  lanes?: LabParticipantEntry[];
373
373
  /** Persona id/label threaded into the actor prompt. Consumed on the app-url route. */
@@ -384,7 +384,7 @@ export interface LabActor {
384
384
  * The two halves belong to different people. `goal` reaches the participant's prompt; `success`
385
385
  * never does — a moderator does not read the success criterion aloud, because telling someone how
386
386
  * they will be judged changes what they do. See src/lab/tasks.ts.
387
- * Supported only on the first actor of per-lane CUA routes; other routes fail preflight.
387
+ * Supported only on the first actor of per-participant CUA routes; other routes fail preflight.
388
388
  */
389
389
  tasks?: LabTask[];
390
390
  /** Provider model override. Consumed on the app-url route. */
@@ -392,35 +392,35 @@ export interface LabActor {
392
392
  /** First-party OpenAI CUA only: per-response output limit including reasoning, not a dollar cap. */
393
393
  maxOutputTokens?: number;
394
394
  /**
395
- * `local-agent` ONLY: which locally signed-in coding agent is the brain. Absent = codex.
395
+ * `local-agent` only: which locally signed-in coding agent is the brain. Absent = codex.
396
396
  *
397
397
  * A separate field from `model` on purpose. The first cut of this route overloaded `model` to
398
- * mean BOTH which CLI and which model, which left no way to say "Claude Code, running Opus" —
398
+ * mean both which CLI and which model, which left no way to say "Claude Code, running Opus":
399
399
  * two different choices wearing one name.
400
400
  */
401
401
  localAgent?: "codex" | "claude";
402
402
  /**
403
- * How hard the model is asked to think, per turn. Lane-level `reasoningEffort` overrides this.
403
+ * How hard the model is asked to think, per turn. A `lanes[]` entry's `reasoningEffort` overrides this.
404
404
  *
405
- * Absent means the PROVIDER's default, and absence is recorded as absence: a run that did not
405
+ * Absent means the provider's default, and absence is recorded as absence: a run that did not
406
406
  * declare an effort does not claim one. Support is model-dependent (see src/actors/reasoning-effort.ts),
407
407
  * so a level a model does not accept fails on the first turn rather than being downgraded.
408
408
  *
409
- * This is a recruiting decision, not a tuning knob: it changes who the participant IS, the same
410
- * way a persona prompt does. Two lanes running the same persona and mission at different efforts
411
- * is therefore a CONTRAST between two participants, not a control for an instrument — a lane that
409
+ * This is a recruiting decision: it changes who the participant is, the same
410
+ * way a persona prompt does. Two participants running the same persona and mission at different efforts
411
+ * is therefore a contrast between two participants. It does not control for an instrument: a participant that
412
412
  * abandons at one level and completes at another has reported on both of them. The obligation it
413
413
  * creates is to declare and record, never to hold it constant. See
414
414
  * docs/principles/actor-fidelity.md.
415
415
  */
416
416
  reasoningEffort?: ReasoningEffort;
417
417
  /**
418
- * Deterministic completion guard used as the default for CUA lanes. Lane-level stopWhen
418
+ * Deterministic completion guard used as the default for CUA participants. A `lanes[]` entry's stopWhen
419
419
  * overrides this value.
420
420
  */
421
421
  stopWhen?: StopWhen;
422
422
  /**
423
- * A declared observation window (#510), the default for every lane; lane-level dwell overrides
423
+ * A declared observation window (#510), the default for every participant; a `lanes[]` entry's dwell overrides
424
424
  * it. `when` is a stopWhen-shaped condition (absent: the window opens after the first
425
425
  * observation); `ms` is the hold, `everyMs` the frame cadence (default 10 s), `then` whether
426
426
  * the participant continues afterwards (default) or the session ends. The harness takes no
@@ -429,9 +429,9 @@ export interface LabActor {
429
429
  dwell?: DwellWindow;
430
430
  }
431
431
  type LabExecutionTarget = "local" | "e2b-desktop" | "e2b-terminal";
432
- /** Terminal transport: the captured non-interactive exec stream (stdin disabled). NOT an
432
+ /** Terminal transport: the captured non-interactive exec stream (stdin disabled). It is not an
433
433
  * interactive duplex PTY — labeling captured exec output "pty" would be a claim/mechanism
434
- * mismatch (invariant 6 + the goal packet's PTY ruling), so this lane uses "exec-stream". */
434
+ * mismatch (invariant 6 + the goal packet's PTY ruling), so this route uses "exec-stream". */
435
435
  type LabTerminalTransport = "exec-stream";
436
436
  /** Whether operator stdin reaches the in-sandbox agent. Disabled by default (the run is
437
437
  * autonomous + comparable to an unassisted baseline). "planned" records intent but sends no
@@ -463,7 +463,7 @@ export interface LabExecutionDesktop {
463
463
  /** Raw hosted screen resolution [width, height] — an escape hatch that overrides `device`. */
464
464
  resolution?: [number, number];
465
465
  /**
466
- * Browser family to launch for hosted desktop actor lanes. Absent/default preserves the
466
+ * Browser family to launch for hosted desktop participants. Absent/default preserves the
467
467
  * historical desktop opener behavior. A concrete value means "launch this browser or fail"
468
468
  * instead of silently accepting the template's default URL opener.
469
469
  */
@@ -471,10 +471,10 @@ export interface LabExecutionDesktop {
471
471
  /** Sandbox server-side timeout. Consumed on the app-url route. */
472
472
  sandboxTimeoutMs?: number;
473
473
  /**
474
- * Custom E2B desktop TEMPLATE (image) the run launches on — a non-empty template NAME or ID —
474
+ * Custom E2B desktop template (image) the run launches on, given as a non-empty template name or ID,
475
475
  * instead of the stock `desktop` template. Lets a subject that needs runtimes the stock image
476
476
  * lacks (e.g. node/bun/a local Postgres baked into an adopter-maintained image) run as-is. Any
477
- * string is a valid template name/id (there is no allowlist). Consumed ONLY on the
477
+ * string is a valid template name/id (there is no allowlist). Consumed only on the
478
478
  * `execution.target: e2b-desktop` computer-use routes (the cua/shared-world/concurrent backends
479
479
  * that call `Sandbox.create`) and the clone scripted-browser route; inert/warned on every route
480
480
  * that creates no desktop. Threaded to
@@ -486,13 +486,13 @@ export interface LabExecutionDesktop {
486
486
  codexAppServer?: boolean;
487
487
  /**
488
488
  * Mobile fidelity beyond viewport size (#221). With `mobileEmulation: true`, every hosted
489
- * Chromium computer-use lane ON A MOBILE PRESET (mobile / small-mobile / narrow-mobile) gets
489
+ * Chromium computer-use participant on a mobile preset (mobile / small-mobile / narrow-mobile) gets
490
490
  * CDP device emulation applied to its launch page before the participant arrives; desktop,
491
- * tablet and wide lanes in the same run are untouched and carry no fidelity block. Applied: the lane's device preset width/height as the CSS viewport, the preset's
491
+ * tablet and wide participants in the same run are untouched and carry no fidelity block. Applied: the participant's device preset width/height as the CSS viewport, the preset's
492
492
  * device pixel ratio (or `deviceScaleFactor`), touch events (`touch`, default true) and a mobile
493
493
  * user agent (`userAgent`, default an iPhone Safari string). The bundle records what the page
494
494
  * then reported about itself under `desktopGeometry.fidelity`; a browser that cannot be
495
- * emulated (Firefox) fails the lane closed instead of shipping a desktop run labelled mobile.
495
+ * emulated (Firefox) fails the participant closed instead of shipping a desktop run labelled mobile.
496
496
  * A held CDP session also applies the overrides to later page targets. Their first observed
497
497
  * viewport and touch read-back is recorded separately; missing or different values warn.
498
498
  */
@@ -505,7 +505,7 @@ export interface LabExecutionDesktop {
505
505
  };
506
506
  }
507
507
  /**
508
- * A participant with a camera (#509): a property of the ENVIRONMENT, like the screen preset and
508
+ * A participant with a camera (#509): a property of the environment, like the screen preset and
509
509
  * the browser, never support for any conferencing product. `camera.source: synthetic` generates
510
510
  * a test pattern in the sandbox with the image's own ffmpeg; a `.y4m` path on the host is
511
511
  * uploaded instead on hosted desktops. `microphone.source: speech` enables the participant's
@@ -535,21 +535,21 @@ export interface LabExecution {
535
535
  /** FORWARD-DECLARED. */
536
536
  completionTimeoutMs?: number;
537
537
  /**
538
- * Bounds in-flight fan-out lanes on the computer-use route. Shared-world needs at least 2 and
538
+ * Bounds in-flight fan-out participants on the computer-use route. Shared-world needs at least 2 and
539
539
  * defaults to the participant count. Inert (warned) elsewhere.
540
540
  */
541
541
  concurrency?: number;
542
542
  desktop?: LabExecutionDesktop;
543
543
  /**
544
- * Blast-radius budget for the computer-use lane. CONSUMED on the CUA route: `caps.maxUsd`, when
545
- * set, is a FAIL-CLOSED abort — the session stops the moment its running ESTIMATED spend crosses
546
- * it (the runaway-retry guard), and a cap on a model src/run/pricing.ts cannot price is REFUSED at
547
- * preflight rather than run uncapped. It is a PER-LANE cap: enforced inside each lane's loop, so
548
- * an N-lane fan-out can spend up to N × maxUsd before any lane aborts (the run warns with the
549
- * true ~N × cap ceiling). `caps.maxTotalUsd` is the shared STUDY budget (#299): one ledger
550
- * across every lane, the knob a researcher actually reasons with. Absent = UNCAPPED (the
544
+ * Blast-radius budget for each computer-use participant. Consumed on the CUA route: `caps.maxUsd`, when
545
+ * set, is a fail-closed abort: the session stops the moment its running estimated spend crosses
546
+ * it (the runaway-retry guard), and a cap on a model src/run/pricing.ts cannot price is refused at
547
+ * preflight rather than run uncapped. It is a PER-PARTICIPANT cap: enforced inside each participant's loop,
548
+ * so an N-participant fan-out can spend up to N × maxUsd before any participant aborts (the run warns with the
549
+ * true ~N × cap ceiling). `caps.maxTotalUsd` is the shared study budget (#299): one ledger
550
+ * across every participant, the knob a researcher actually reasons with. Absent = uncapped (the
551
551
  * historical CUA behavior); maxUsd: 0 still permits a request before reported usage trips it. Inert
552
- * (warned) on non-CUA routes. Reuses the same LabScenarioCaps shape as the terminal lane's
552
+ * (warned) on non-CUA routes. Reuses the same LabScenarioCaps shape as the terminal route's
553
553
  * `scenario.caps` (not a fork).
554
554
  */
555
555
  caps?: LabScenarioCaps;
@@ -572,7 +572,7 @@ export interface LabExecution {
572
572
  * wrong host list fails studies in ways that look like product bugs. Opt in per lab.
573
573
  *
574
574
  * Domain filtering covers HTTP on :80 (Host header) and TLS on :443 (SNI); anything else needs
575
- * an IP or CIDR. `*.example.com` matches subdomains at any depth and NOT the apex, which needs
575
+ * an IP or CIDR. `*.example.com` matches subdomains at any depth and not the apex, which needs
576
576
  * its own entry.
577
577
  */
578
578
  egressAllow?: string[];
@@ -592,12 +592,12 @@ export interface LabScenarioCaps {
592
592
  /**
593
593
  * STUDY-LEVEL model-spend budget (#299), the number a researcher actually reasons with: "this
594
594
  * study is N participants, roughly $X" — decided once, up front, where recruiting decisions are
595
- * made. The computer-use route reads it from `execution.caps.maxTotalUsd` only: every lane's
596
- * running ESTIMATED model spend feeds one shared ledger, and the moment the run total crosses
597
- * this, each lane stops at its next turn with an honest `budget_reached` (status `incomplete` —
595
+ * made. The computer-use route reads it from `execution.caps.maxTotalUsd` only: every participant's
596
+ * running estimated model spend feeds one shared ledger, and the moment the run total crosses
597
+ * this, each participant stops at its next turn with an honest `budget_reached` (status `incomplete` —
598
598
  * the participant ran out of budget; never `gave_up`, because a study-level stop is not the
599
- * participant's doing). Estimated MODEL spend only — desktop-minutes ride the cost summary but
600
- * not this ledger. Independent of the per-lane `maxUsd` backstop; either, both, or neither may
599
+ * participant's doing). Estimated model spend only; desktop-minutes ride the cost summary but
600
+ * not this ledger. Independent of the per-participant `maxUsd` backstop; either, both, or neither may
601
601
  * be set. A positive `scenario.caps.maxTotalUsd` on a computer-use lab is a parse error; on the
602
602
  * terminal route it is inert (warned), since the single agent's maxUsd already caps the run.
603
603
  */
@@ -608,8 +608,8 @@ export interface LabScenarioCaps {
608
608
  maxMinutes?: number;
609
609
  }
610
610
  export interface LabScenario {
611
- /** Reference a committed scenario by id (humanish/scenarios/<ref>.yaml) or path. CONSUMED
612
- * (and REQUIRED) on the scripted-browser route; FORWARD-DECLARED elsewhere. */
611
+ /** Reference a committed scenario by id (humanish/scenarios/<ref>.yaml) or path. Consumed
612
+ * (and required) on the scripted-browser route; FORWARD-DECLARED elsewhere. */
613
613
  ref?: string;
614
614
  /** Or inline the scenario body. FORWARD-DECLARED (PR #2). */
615
615
  inline?: Record<string, unknown>;
@@ -622,14 +622,14 @@ export interface LabScenario {
622
622
  export interface LabPolicies {
623
623
  /**
624
624
  * Redact target repo labels in durable artifacts. Consumed on the computer-use,
625
- * scripted-browser and shared-world clone routes (provenance), where it DEFAULTS to true when
625
+ * scripted-browser and shared-world clone routes (provenance), where it defaults to true when
626
626
  * the clone authenticates via GITHUB_TOKEN (a token-bearing clone is treated as private until
627
627
  * declared otherwise).
628
628
  */
629
629
  redactRepos?: boolean;
630
630
  /**
631
- * Blur+downscale persisted screenshots on the computer-use route. Default FALSE — the common
632
- * case is watching a sim of your OWN app locally (gitignored .humanish), where full fidelity is
631
+ * Blur+downscale persisted screenshots on the computer-use route. Default `false`; the common
632
+ * case is watching a sim of your own app locally (gitignored .humanish), where full fidelity is
633
633
  * the deliverable. Set true for unowned subjects or bundles meant to be shared as-is. The
634
634
  * provider always sees raw frames; this only governs what is persisted. Raw bundles stay
635
635
  * local (gitignored, commit-scan-guarded); a redact-on-export step for them is planned.
@@ -637,8 +637,8 @@ export interface LabPolicies {
637
637
  redactScreenshots?: boolean;
638
638
  /**
639
639
  * Allow an app-url subject to point at a non-loopback (public/preview/staging) URL the lab
640
- * owner declares. Default FALSE (loopback-only). The invariant is "the actor drives a target
641
- * the owner declared" — setting this IS that declaration (e.g. a Vercel preview of your app).
640
+ * owner declares. Default `false` (loopback-only). The invariant is "the actor drives a target
641
+ * the owner declared"; setting this is that declaration (e.g. a Vercel preview of your app).
642
642
  */
643
643
  allowPublicTargets?: boolean;
644
644
  /**
@@ -669,7 +669,7 @@ export interface LabReview {
669
669
  vocabulary?: string;
670
670
  /**
671
671
  * #316 code escape hatch: a repo-relative path to an adopter scorer module (.mjs recommended) that
672
- * exports any of `{score, deriveFeedback, deriveArtifacts}`. CONSUMED on the scorer-capable routes
672
+ * exports any of `{score, deriveFeedback, deriveArtifacts}`. Consumed on the scorer-capable routes
673
673
  * (terminal / computer-use / shared-world); loaded fail-closed (typed error, pre-spend). The entry
674
674
  * is executable code — review a PR that adds one as code, not config.
675
675
  */
@@ -723,8 +723,8 @@ interface LabCommsCaptureEmail {
723
723
  /**
724
724
  * The subject-env var the harness sets to the in-sandbox catch's base URL — ADOPTER-NAMED (an app
725
725
  * calling Resend's API directly reads `RESEND_API_URL`; an app using the SDK reads `RESEND_BASE_URL`).
726
- * The value is computed by the harness (a loopback URL), so it is NOT declared in `subject.env`.
727
- * REQUIRED on the provisioned routes; absent (and meaningless) when `external` is declared,
726
+ * The value is computed by the harness (a loopback URL), so it is not declared in `subject.env`.
727
+ * Required on the provisioned routes; absent (and meaningless) when `external` is declared,
728
728
  * because there the adopter runs the catch and points their own app at it.
729
729
  */
730
730
  injectEnv?: string;
@@ -746,14 +746,14 @@ interface LabCommsCaptureEmail {
746
746
  * prepended to the inbox link-origin rewrite so the persona's clicked link resolves to a reachable
747
747
  * host. Omit when the app emits loopback links (the default derivation covers those). */
748
748
  linkOrigin?: string;
749
- /** Each lane's inbox address: the actor is TOLD to sign up with it (the injected inbox
749
+ /** Each participant's inbox address: the actor is told to sign up with it (the injected inbox
750
750
  * instruction carries it) and the teardown drain matches captured mail against it. Omit the
751
- * whole list and the parser fills one deterministic address per lane (`<laneId>@example.test`)
752
- * so every seat can do email out of the box (#351). When declared: a `lane` naming a lane that
751
+ * whole list and the parser fills one deterministic address per participant (`<laneId>@example.test`)
752
+ * so every seat can do email out of the box (#351). When declared: a `lane` naming a participant that
753
753
  * does not exist is a hard parse error (a mismatch silently disables the funnel for that seat),
754
- * zero covered lanes is a hard error, and partial coverage warns with the uncovered lanes. An
755
- * entry without `address` is legal but inert for the funnel — it is NOT matched by the drain
756
- * and its lane gets no inbox instruction; captured mail to an undeclared address is warned,
754
+ * zero covered participants is a hard error, and partial coverage warns with the uncovered ones. An
755
+ * entry without `address` is legal but inert for the funnel: the drain does not match it,
756
+ * and its participant gets no inbox instruction; captured mail to an undeclared address is warned,
757
757
  * never silently dropped. */
758
758
  recipients?: LabCommsRecipient[];
759
759
  /**
@@ -771,13 +771,13 @@ export interface LabCommsExternal {
771
771
  catchBaseUrl: string;
772
772
  /** Where the persona opens its inbox. Defaults to catchBaseUrl (one server serves both). */
773
773
  inboxBaseUrl?: string;
774
- /** Env var NAME holding the bearer token for the drain read. The NAME is recorded as evidence;
774
+ /** Env var name holding the bearer token for the drain read. The name is recorded as evidence;
775
775
  * the value is read at runtime and never persisted (the credential-boundary discipline). */
776
776
  authTokenEnv?: string;
777
777
  }
778
778
  export interface LabCommsRecipient {
779
779
  lane: string;
780
- /** The literal address the app sends to — what the evidence drain matches. Omit to reserve the lane
780
+ /** The literal address the app sends to — what the evidence drain matches. Omit to reserve the participant
781
781
  * for the persona surface's default address (not drain-matched). */
782
782
  address?: string;
783
783
  }