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
@@ -5,23 +5,23 @@ import { containsSensitive } from "../../evidence/redaction.js";
5
5
  import { ENV_NAME_PATTERN, invalid, posInt, str, strList } from "./values.js";
6
6
  import { isRecord } from "../../run/type-guards.js";
7
7
  /**
8
- * LITERAL non-secret subject env. Real apps need configuration before they will boot — a public base
9
- * URL, a transport selector, a feature flag — and none of that is secret. Routing it through
8
+ * Literal non-secret subject env. Real apps need configuration before they will boot: a public base
9
+ * URL, a transport selector, a feature flag, and none of that is secret. Routing it through
10
10
  * `subject.env` would force an adopter to carry a private env file just to reproduce a public study.
11
11
  *
12
- * These values ARE recorded in evidence (they are part of how the subject was configured), so a
12
+ * These values are recorded in evidence (they are part of how the subject was configured), so a
13
13
  * value that looks like a credential is refused here rather than committed to a public repo.
14
14
  */
15
15
  export function parseEnvValues(raw) {
16
16
  if (raw === undefined)
17
17
  return { ok: true };
18
18
  if (!isRecord(raw)) {
19
- return invalid("`subject.envValues` must be a mapping of env var NAME to a literal non-secret value.");
19
+ return invalid("`subject.envValues` must map environment variable names to literal values that are not secret.");
20
20
  }
21
21
  const envValues = {};
22
22
  for (const [name, rawValue] of Object.entries(raw)) {
23
23
  if (!ENV_NAME_PATTERN.test(name)) {
24
- return invalid(`subject.envValues keys must be env var NAMES like NEXT_PUBLIC_APP_URL (got "${name}").`);
24
+ return invalid(`subject.envValues keys must be environment variable names like NEXT_PUBLIC_APP_URL, and "${name}" is not one.`);
25
25
  }
26
26
  const value = typeof rawValue === "number" || typeof rawValue === "boolean"
27
27
  ? String(rawValue)
@@ -30,9 +30,9 @@ export function parseEnvValues(raw) {
30
30
  return invalid(`\`subject.envValues.${name}\` must be a string, number, or boolean.`);
31
31
  }
32
32
  // Reuse the redaction module's own detector rather than inventing a second opinion about what
33
- // a secret looks like — the two must never disagree about the same string.
33
+ // a secret looks like; the two must never disagree about the same string.
34
34
  if (containsSensitive(value)) {
35
- return invalid(`\`subject.envValues.${name}\` looks like a secret or a local path, and these values are committed with the lab and recorded in evidence. Declare the NAME in \`subject.env\` instead — those values come from the caller's environment and never persist.`);
35
+ return invalid(`\`subject.envValues.${name}\` looks like a secret or a local path, and envValues are committed with the study and recorded in evidence. List the name in \`subject.env\` instead: its value then comes from your environment and is never stored.`);
36
36
  }
37
37
  envValues[name] = value;
38
38
  }
@@ -41,8 +41,8 @@ export function parseEnvValues(raw) {
41
41
  /**
42
42
  * Structural parse of `subject.state` into a candidate LabSubjectState. Deliberately keeps
43
43
  * unrecognized `when`/`timeoutMs` values in the candidate (instead of silently dropping
44
- * them) so subjectStateInvalidReason rejects them — a state declaration that silently does
45
- * less than it says would violate invariant 6.
44
+ * them) so subjectStateInvalidReason rejects them: a state declaration that silently does
45
+ * less than it says would claim more than its mechanism does.
46
46
  */
47
47
  export function parseState(raw) {
48
48
  if (raw === undefined) {
@@ -68,7 +68,7 @@ export function parseState(raw) {
68
68
  if (raw.external !== undefined) {
69
69
  const external = strList(raw.external);
70
70
  if (!external) {
71
- return invalid("`subject.state.external` must be a non-empty list of env var NAMES when set.");
71
+ return invalid("`subject.state.external` must be a non-empty list of environment variable names when it is set.");
72
72
  }
73
73
  state.external = external;
74
74
  }
@@ -79,7 +79,7 @@ export function parseState(raw) {
79
79
  state.checkpoint = raw.checkpoint.map((probe) => ({
80
80
  name: typeof probe.name === "string" ? probe.name.trim() : "",
81
81
  command: typeof probe.command === "string" ? probe.command.trim() : "",
82
- // Preserve the redact list verbatim (literal secret values may contain commas, so do NOT
82
+ // Preserve the redact list verbatim (literal secret values may contain commas, so do not
83
83
  // run it through the comma-splitting strList); subjectStateInvalidReason validates the shape.
84
84
  ...(probe.redact === undefined ? {} : { redact: probe.redact }),
85
85
  }));
@@ -87,7 +87,7 @@ export function parseState(raw) {
87
87
  return { ok: true, value: state };
88
88
  }
89
89
  // The step name interpolates into in-sandbox script/status/log paths (`subject-state-<name>`);
90
- // the strict shape is load-bearing, exactly like the repo slug.
90
+ // so the shape is strict, exactly like the repo slug.
91
91
  const STATE_STEP_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
92
92
  const STATE_STEP_NAME_MAX_CHARS = 40;
93
93
  const STATE_STEP_WHENS = [
@@ -97,9 +97,9 @@ const STATE_STEP_WHENS = [
97
97
  ];
98
98
  /**
99
99
  * Semantic validation for `subject.state`, shared by parseLabConfig and the engine
100
- * (runCuaActorLab re-enforces it on configs that arrive through the library API). Returns
100
+ * (the route re-enforces it on configs that arrive through runLab). Returns
101
101
  * the failure message, or null when the declaration is valid. Reads the candidate
102
- * defensively — library callers can hand the engine arbitrarily-shaped objects.
102
+ * defensively: library callers can hand the engine arbitrarily-shaped objects.
103
103
  */
104
104
  export function subjectStateInvalidReason(state, env) {
105
105
  const seed = state.seed;
@@ -140,11 +140,11 @@ export function subjectStateInvalidReason(state, env) {
140
140
  }
141
141
  if (external !== undefined) {
142
142
  if (!Array.isArray(external) || external.length === 0) {
143
- return "`subject.state.external` must be a non-empty list of env var NAMES when set.";
143
+ return "`subject.state.external` must be a non-empty list of environment variable names when it is set.";
144
144
  }
145
145
  for (const name of external) {
146
146
  if (typeof name !== "string" || !ENV_NAME_PATTERN.test(name)) {
147
- return "subject.state.external entries must be env var NAMES like DATABASE_URL; values come from the caller's environment and are never persisted.";
147
+ return "subject.state.external entries must be environment variable names like DATABASE_URL. Their values come from your environment and are never stored.";
148
148
  }
149
149
  if (!env?.includes(name)) {
150
150
  return "subject.state.external names must also be declared in subject.env (the declaration must name a provisioned channel).";
@@ -17,9 +17,9 @@ export function parseSubject(raw) {
17
17
  return invalid("`subject.source` must be one of: this-repo, clone, app-url, local-app, terminal-product, desktop-cli, local-tree.");
18
18
  }
19
19
  const subject = { source };
20
- // topology is enum-validated everywhere; its SEMANTICS (shared-world requires clone × e2b-desktop
20
+ // topology is enum-validated everywhere; its semantics (shared-world requires clone × e2b-desktop
21
21
  // × a ≥2 roster) are enforced in the shared-world cross-validation below, and a set-but-unconsumed
22
- // topology warns as inert off the shared-world route (invariant 6).
22
+ // topology warns as inert off the shared-world route.
23
23
  if (raw.topology !== undefined) {
24
24
  const topology = str(raw.topology);
25
25
  if (topology !== "per-lane-worlds" && topology !== "shared-world") {
@@ -27,12 +27,12 @@ export function parseSubject(raw) {
27
27
  }
28
28
  subject.topology = topology;
29
29
  }
30
- // exposure is enum-validated everywhere; it is REQUIRED on the concurrent shared-world route (the
30
+ // exposure is enum-validated everywhere; it is required on the concurrent shared-world route (the
31
31
  // getHost synthetic-subject attestation) and warns inert elsewhere.
32
32
  if (raw.exposure !== undefined) {
33
33
  const exposure = str(raw.exposure);
34
34
  if (exposure !== "synthetic") {
35
- return invalid("`subject.exposure` must be `synthetic` (the author attestation that the getHost-exposed subject is synthetic seeded data).");
35
+ return invalid("`subject.exposure` must be `synthetic`: your statement that the subject served on a public sandbox URL holds only synthetic seeded data.");
36
36
  }
37
37
  subject.exposure = exposure;
38
38
  }
@@ -57,15 +57,15 @@ export function parseSubject(raw) {
57
57
  }
58
58
  /** The first field set on a source it cannot act on, in the order parseSubject has always checked. */
59
59
  function misplacedFieldFailure(source, raw) {
60
- // `product` is terminal-product-only; reject it elsewhere (invariant 6: a field that cannot act
61
- // on this route is an honest parse error, not silently dropped).
60
+ // `product` is terminal-product-only; reject it elsewhere. A field that cannot act on this
61
+ // route is a parse error and is never silently dropped.
62
62
  if (source !== "terminal-product" && source !== "desktop-cli" && raw.product !== undefined) {
63
63
  return invalid("`subject.product` applies only to terminal-product and desktop-cli subjects (the CLI a participant studies from public surfaces).");
64
64
  }
65
- // appUrl is app-url/local-app-only; a terminal-product subject drives PUBLIC surfaces, not a
66
- // single loopback app — reject appUrl on it.
65
+ // appUrl is app-url/local-app-only; a terminal-product subject drives public surfaces instead of a
66
+ // single loopback app, so reject appUrl on it.
67
67
  if (source === "terminal-product" && raw.appUrl !== undefined) {
68
- return invalid("`subject.appUrl` does not apply to terminal-product subjects — declare `subject.product.publicSurfaces` (the agent works from public surfaces, not one loopback app).");
68
+ return invalid("`subject.appUrl` does not apply to a terminal-product subject: its agent works from the product's public pages. List them in `subject.product.publicSurfaces` instead.");
69
69
  }
70
70
  // serve/env/state are shared between clone (cloned app) and local-tree (packed working
71
71
  // tree): both routes serve a subject in-sandbox with the same install/build/start/url +
@@ -79,7 +79,7 @@ function misplacedFieldFailure(source, raw) {
79
79
  if (source !== "clone" && source !== "local-tree" && raw.state !== undefined) {
80
80
  return invalid("`subject.state` applies only to clone subjects or local-tree subjects (the lab seeds the state it serves).");
81
81
  }
82
- // repos/clone are clone-ONLY (a fresh-clone subject's git inputs). local-tree packs the
82
+ // repos/clone are clone-only (a fresh-clone subject's git inputs). local-tree packs the
83
83
  // resolution cwd itself, so it has no repo slug to clone and gets its own precise reasons
84
84
  // rather than falling through to the generic clone-only message below.
85
85
  if (source === "local-tree" && raw.repos !== undefined) {
@@ -89,19 +89,19 @@ function misplacedFieldFailure(source, raw) {
89
89
  return invalid("`subject.clone` does not apply to local-tree subjects. Declare `subject.localTree` instead (keep/exclude/maxArchiveBytes).");
90
90
  }
91
91
  // Rejected, never silently dropped, on app-url/local-app/this-repo/terminal-product subjects
92
- // too (invariant 6: a field that cannot act on this route is an honest parse error).
92
+ // too: a field that cannot act on this route is a parse error.
93
93
  if (source !== "clone" && raw.repos !== undefined) {
94
94
  return invalid("`subject.repos` applies only to clone subjects (the owner/repo slugs to clone).");
95
95
  }
96
96
  if (source !== "clone" && raw.clone !== undefined) {
97
97
  return invalid("`subject.clone` applies only to clone subjects (clone depth/fanout/keep).");
98
98
  }
99
- // localTree is local-tree-ONLY (pack/upload knobs for the packed working tree).
99
+ // localTree is local-tree-only (pack/upload knobs for the packed working tree).
100
100
  if (source !== "local-tree" && raw.localTree !== undefined) {
101
101
  return invalid("`subject.localTree` applies only to local-tree subjects (keep/exclude/maxArchiveBytes for packing the working tree).");
102
102
  }
103
- // publicTarget is app-url-ONLY (the external-public shared-world ownership attestation). It is
104
- // meaningless without a real public deployment as the plane — reject it elsewhere (invariant 6).
103
+ // publicTarget is app-url-only (the external-public shared-world ownership attestation). It is
104
+ // meaningless without a real public deployment as the plane, so reject it elsewhere.
105
105
  if (source !== "app-url" && raw.publicTarget !== undefined) {
106
106
  return invalid("`subject.publicTarget` applies only to app-url subjects on the external-public shared-world route (the operator's ownership attestation for a real public deployment used directly as the shared plane).");
107
107
  }
@@ -125,7 +125,7 @@ function parseCloneSubject(raw, subject) {
125
125
  }
126
126
  function parseLocalTreeSubject(raw, subject) {
127
127
  // A local-tree subject exists to be packed and served; there is no other way to boot it, so
128
- // serve is REQUIRED here. Clone subjects get the same requirement from each route's checks in
128
+ // serve is required here. Clone subjects get the same requirement from each route's checks in
129
129
  // parseLabConfig.
130
130
  if (raw.serve === undefined) {
131
131
  return invalid("`subject.serve` is required when source is local-tree: a local-tree subject exists to be packed and served, so declare install/build/start/url exactly like the clone route.");
@@ -157,11 +157,11 @@ function parseServedApp(raw, subject) {
157
157
  if (raw.env !== undefined) {
158
158
  const env = strList(raw.env);
159
159
  if (!env || env.length === 0) {
160
- return invalid("`subject.env` must be a non-empty list of env var NAMES when set.");
160
+ return invalid("`subject.env` must be a non-empty list of environment variable names when it is set.");
161
161
  }
162
162
  const badName = env.find((name) => !ENV_NAME_PATTERN.test(name));
163
163
  if (badName) {
164
- return invalid(`subject.env entries must be env var NAMES like DATABASE_URL (got "${badName}"); values come from the caller's environment and are never persisted.`);
164
+ return invalid(`subject.env entries must be environment variable names like DATABASE_URL, and "${badName}" is not one. Their values come from your environment and are never stored.`);
165
165
  }
166
166
  subject.env = env;
167
167
  }
@@ -192,11 +192,11 @@ function parseAppSubject(raw, source, subject) {
192
192
  }
193
193
  // app-url: shape-only here; the loopback-vs-public-target gate is applied in the
194
194
  // cross-validation block below, where policies.allowPublicTargets is available.
195
- // local-app: an in-process local dev server — ALWAYS loopback (no public-target option),
195
+ // local-app: an in-process local dev server, always loopback (no public-target option),
196
196
  // so the loopback wall is enforced right here at parse.
197
197
  if (source === "local-app") {
198
198
  if (!isLoopbackUrl(appUrl)) {
199
- return invalid("`subject.appUrl` must be a loopback URL (127.0.0.1/localhost) on a local-app subject — it drives an already-running LOCAL dev server in-process; public targets are not supported on this route.");
199
+ return invalid("`subject.appUrl` must be a loopback URL (127.0.0.1 or localhost) on a local-app subject: humanish drives your running dev server from this process, so it cannot reach a public URL.");
200
200
  }
201
201
  }
202
202
  else if (!isHttpUrl(appUrl)) {
@@ -204,7 +204,7 @@ function parseAppSubject(raw, source, subject) {
204
204
  }
205
205
  subject.appUrl = appUrl;
206
206
  // publicTarget (external-public shared-world ownership attestation) is app-url-only. Shape it
207
- // here; its REQUIRED-on-that-route semantics live in externalPublicSharedWorldValidationReason.
207
+ // here; its required-on-that-route semantics live in externalPublicSharedWorldValidationReason.
208
208
  if (source === "app-url" && raw.publicTarget !== undefined) {
209
209
  const publicTargetResult = parsePublicTarget(raw.publicTarget);
210
210
  if (!publicTargetResult.ok) {
@@ -226,22 +226,22 @@ function parseProductSubject(raw, subject) {
226
226
  // "example-operator/lobby-trivia" or a bare org name). Slash allowed for the owner/repo convention.
227
227
  export const PUBLIC_TARGET_OWNER_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_./-]*$/;
228
228
  /** Parse the external-public shared-world ownership attestation ({ owner, authorized: true }). The
229
- * harness cannot verify ownership — this is author-trust, surfaced honestly in the evidence class. */
229
+ * harness cannot verify ownership: this is author-trust, and the evidence class says so. */
230
230
  function parsePublicTarget(raw) {
231
231
  if (!isRecord(raw)) {
232
- return invalid("`subject.publicTarget` must be an object ({ owner, authorized: true }) — the operator's ownership attestation for the external-public shared plane.");
232
+ return invalid("`subject.publicTarget` must be an object, `{ owner, authorized: true }`, declaring that you own or operate the public deployment.");
233
233
  }
234
234
  const owner = str(raw.owner);
235
235
  if (!owner || !PUBLIC_TARGET_OWNER_PATTERN.test(owner)) {
236
236
  return invalid("`subject.publicTarget.owner` must be a public-safe operator/repo label (e.g. owner/repo); it is recorded in evidence, so it must carry no secret.");
237
237
  }
238
238
  if (raw.authorized !== true) {
239
- return invalid("`subject.publicTarget.authorized` must be true — you must attest you own/operate the public deployment used as the shared plane (author-trust; the harness cannot verify ownership).");
239
+ return invalid("`subject.publicTarget.authorized` must be true to declare that you own or operate the public deployment. humanish cannot check ownership, so the study states it.");
240
240
  }
241
241
  return { ok: true, value: { owner, authorized: true } };
242
242
  }
243
243
  // The product name interpolates into evidence labels and the composed prompt; the public-safe
244
- // token shape is the same load-bearing constraint as a lab id.
244
+ // token shape is the same strict constraint as a lab id.
245
245
  const PRODUCT_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
246
246
  function parseProduct(raw) {
247
247
  if (!isRecord(raw)) {
@@ -263,7 +263,7 @@ function parseProduct(raw) {
263
263
  if (upload.startsWith("/") ||
264
264
  /^[A-Za-z]:/.test(upload) ||
265
265
  upload.split(/[\\/]/).includes("..")) {
266
- return invalid("`subject.product.upload` must stay inside the project — no absolute paths and no `..` segments.");
266
+ return invalid("`subject.product.upload` must stay inside the project: use a relative path with no `..` segments.");
267
267
  }
268
268
  }
269
269
  const install = str(raw.install);
@@ -289,7 +289,7 @@ function parseProduct(raw) {
289
289
  },
290
290
  };
291
291
  }
292
- // Public-safe stance: a computer-use actor's ENTRY URL is always an app the lab owner runs on
292
+ // Public-safe stance: a computer-use actor's entry URL is always an app the lab owner runs on
293
293
  // loopback (inside the sandbox), never an arbitrary public site. (The constraint binds the
294
294
  // entry point; a navigation watchdog for mid-session escapes is a later slice.) Exported so
295
295
  // the engine re-enforces the same boundary on configs that arrive through the library API.
@@ -330,7 +330,7 @@ function parseServe(raw) {
330
330
  }
331
331
  const url = str(raw.url);
332
332
  if (!url || !isLoopbackUrl(url)) {
333
- return invalid("`subject.serve.url` must be a loopback http(s) URL (127.0.0.1 or localhost) — the app is served INSIDE the sandbox.");
333
+ return invalid("`subject.serve.url` must be a loopback http(s) URL (127.0.0.1 or localhost), because the app runs inside the sandbox.");
334
334
  }
335
335
  const serve = { start, url };
336
336
  const install = str(raw.install);
@@ -368,7 +368,7 @@ function parseClone(raw) {
368
368
  /**
369
369
  * Structural parse of `subject.localTree`, mirroring parseClone. Unlike parseClone (which
370
370
  * silently drops an out-of-range depth/fanout), an invalid exclude/maxArchiveBytes value is
371
- * REJECTED, never silently dropped: a caller who typed an empty exclude entry or a non-positive
371
+ * rejected, never silently dropped: a caller who typed an empty exclude entry or a non-positive
372
372
  * maxArchiveBytes almost certainly meant something, and the archive-size cap is a safety knob,
373
373
  * not a cosmetic default.
374
374
  */
@@ -11,6 +11,6 @@ export declare function strList(value: unknown): string[] | undefined;
11
11
  */
12
12
  export declare function readPositiveInt(value: string | undefined, fallback: number): number;
13
13
  export declare function posInt(value: unknown): number | undefined;
14
- /** A non-negative finite number (0 allowed — caps default to 0 = no-spend). Accepts a numeric
14
+ /** A non-negative finite number (0 allowed; caps default to 0 = no-spend). Accepts a numeric
15
15
  * string too, since YAML scalars can arrive as strings. */
16
16
  export declare function nonNegNumber(value: unknown): number | undefined;
@@ -1,8 +1,8 @@
1
- // The slug interpolates into an in-sandbox shell command; the strict shape is load-bearing.
1
+ // The slug interpolates into an in-sandbox shell command, so its shape is strict.
2
2
  export const REPO_SLUG_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
3
3
  export const ENV_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
4
4
  export function invalid(message) {
5
- return { ok: false, error: { code: "HUMANISH_LAB_INVALID", message } };
5
+ return { ok: false, error: { code: "HUMANISH_STUDY_INVALID", message } };
6
6
  }
7
7
  export function str(value) {
8
8
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
@@ -48,7 +48,7 @@ export function posInt(value) {
48
48
  }
49
49
  return undefined;
50
50
  }
51
- /** A non-negative finite number (0 allowed — caps default to 0 = no-spend). Accepts a numeric
51
+ /** A non-negative finite number (0 allowed; caps default to 0 = no-spend). Accepts a numeric
52
52
  * string too, since YAML scalars can arrive as strings. */
53
53
  export function nonNegNumber(value) {
54
54
  if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
@@ -4,7 +4,7 @@ import type { LabActor } from "./types.js";
4
4
  /** Title-case an id for the fallback display name (`skeptical-power-user` -> `Skeptical Power User`). */
5
5
  export declare function personaTitleFromId(personaId: string): string;
6
6
  /**
7
- * Resolve ONE persona from `humanish/personas/`, then the ignored `.humanish/local/personas/`.
7
+ * Resolve one persona from `humanish/personas/`, then the ignored `.humanish/local/personas/`.
8
8
  * Returns `null` with a warning when the id is unsafe or no file exists. Invalid rich backgrounds
9
9
  * reject the study before execution.
10
10
  */
@@ -14,7 +14,7 @@ export declare function resolveCommittedPersona(projectRoot: PreparedSelectedOut
14
14
  }>;
15
15
  /**
16
16
  * Resolve every distinct persona id a run will use, once, before participant specs are built. Returning a
17
- * map keeps the plan builder PURE (it is exported npm surface and asserted pure by tests): the
17
+ * map keeps the plan builder pure (it is exported npm surface and asserted pure by tests): the
18
18
  * async file reads happen here, and the composer only does a lookup.
19
19
  */
20
20
  export declare function resolveCommittedPersonas(projectRoot: PreparedSelectedOutputDirectory, personaIds: readonly (string | undefined)[]): Promise<{
@@ -30,8 +30,8 @@ export declare function labPersonaIds(config: {
30
30
  }): string[];
31
31
  /**
32
32
  * Same resolution from a plain cwd, for the labs that carry a directory string rather than an
33
- * already-prepared root. Realpath-then-prepare mirrors the cua lab so a symlinked cwd still reads
34
- * personas from the physical project.
33
+ * already-prepared root. Realpath-then-prepare mirrors the computer-use route so a symlinked cwd
34
+ * still reads personas from the physical project.
35
35
  */
36
36
  export declare function resolveCommittedPersonasForCwd(cwd: string, personaIds: readonly (string | undefined)[]): Promise<{
37
37
  personas: Map<string, ResolvedPersona>;
@@ -22,7 +22,7 @@ const PERSONA_DIRECTORIES = [
22
22
  path.posix.join(".humanish", "local", "personas"),
23
23
  ];
24
24
  /**
25
- * Resolve ONE persona from `humanish/personas/`, then the ignored `.humanish/local/personas/`.
25
+ * Resolve one persona from `humanish/personas/`, then the ignored `.humanish/local/personas/`.
26
26
  * Returns `null` with a warning when the id is unsafe or no file exists. Invalid rich backgrounds
27
27
  * reject the study before execution.
28
28
  */
@@ -66,7 +66,7 @@ export async function resolveCommittedPersona(projectRoot, personaId) {
66
66
  }
67
67
  /**
68
68
  * Resolve every distinct persona id a run will use, once, before participant specs are built. Returning a
69
- * map keeps the plan builder PURE (it is exported npm surface and asserted pure by tests): the
69
+ * map keeps the plan builder pure (it is exported npm surface and asserted pure by tests): the
70
70
  * async file reads happen here, and the composer only does a lookup.
71
71
  */
72
72
  export async function resolveCommittedPersonas(projectRoot, personaIds) {
@@ -98,8 +98,8 @@ export function labPersonaIds(config) {
98
98
  }
99
99
  /**
100
100
  * Same resolution from a plain cwd, for the labs that carry a directory string rather than an
101
- * already-prepared root. Realpath-then-prepare mirrors the cua lab so a symlinked cwd still reads
102
- * personas from the physical project.
101
+ * already-prepared root. Realpath-then-prepare mirrors the computer-use route so a symlinked cwd
102
+ * still reads personas from the physical project.
103
103
  */
104
104
  export async function resolveCommittedPersonasForCwd(cwd, personaIds) {
105
105
  try {
@@ -44,14 +44,14 @@ export interface ComputerUseParticipant extends DesktopParticipant {
44
44
  /** app-url fan-out only: this participant's own entry URL; absent means the subject URL. */
45
45
  readonly targetUrl?: string;
46
46
  }
47
- /** A seat on a provisioned plane: an optional same-origin path under `serve.url`. */
47
+ /** A participant on a provisioned plane: an optional same-origin path under `serve.url`. */
48
48
  export interface ProvisionedParticipant extends DesktopParticipant {
49
49
  readonly entry?: string;
50
50
  readonly host?: never;
51
51
  readonly tasks?: never;
52
52
  readonly targetUrl?: never;
53
53
  }
54
- /** A seat on an external public plane: exactly one seat hosts the shared session. */
54
+ /** A participant on an external public plane: exactly one participant hosts the shared session. */
55
55
  export interface ExternalPublicParticipant extends DesktopParticipant {
56
56
  readonly host: boolean;
57
57
  readonly entry?: never;
@@ -4,7 +4,7 @@ import type { ReasoningEffort } from "../actors/reasoning-effort.js";
4
4
  import type { BrowserSurface } from "../actors/scripted-browser/types.js";
5
5
  import type { ScriptedRefusal } from "../routes/scripted/plan.js";
6
6
  import type { TerminalRefusal } from "../routes/terminal/plan.js";
7
- import type { RunLabProvenance } from "../run/status.js";
7
+ import type { RunStudyProvenance } from "../run/study-provenance.js";
8
8
  import type { ComputerUseRefusal } from "../routes/computer-use/plan.js";
9
9
  import type { SharedWorldRefusal } from "../routes/shared-world/plan.js";
10
10
  import type { ComputerUseParticipant, ExternalPublicParticipant, ProvisionedParticipant } from "./plan-participants.js";
@@ -62,7 +62,7 @@ interface PlanBase {
62
62
  readonly labId: string;
63
63
  /** The lab's declared title, which bundles record. */
64
64
  readonly title?: string;
65
- readonly lab?: RunLabProvenance;
65
+ readonly lab?: RunStudyProvenance;
66
66
  /** A frozen copy owned by the plan. */
67
67
  readonly residual: Readonly<ResidualConfig>;
68
68
  readonly dryRun: boolean;
@@ -194,7 +194,7 @@ export interface SharedWorldPlan extends PlanBase {
194
194
  readonly plane: SharedWorldPlane;
195
195
  /** At least 2. */
196
196
  readonly concurrency: number;
197
- /** The declared seat session timeout; the route supplies its default. */
197
+ /** The declared participant session timeout; the route supplies its default. */
198
198
  readonly sessionTimeoutMs?: number;
199
199
  readonly brain: Extract<Brain, {
200
200
  kind: "openai" | "local-agent";
@@ -282,7 +282,7 @@ export type RoutePlanResult<Plan, Refusal> = {
282
282
  readonly refusal: Refusal;
283
283
  };
284
284
  /** The error codes the preview route returns before a run starts. */
285
- export type PreviewRefusalCode = "HUMANISH_LAB_COMMS_UNSUPPORTED" | "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_ANALYSIS_UNSUPPORTED" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED";
285
+ export type PreviewRefusalCode = "HUMANISH_STUDY_COMMS_UNSUPPORTED" | "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_ANALYSIS_UNSUPPORTED" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_INVALID_PARTICIPANT_COUNT" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED";
286
286
  /** Why planLab refused: the route's own code and message, as its runner returns them. */
287
287
  export type PlanRefusal = RouteRefusal<"preview", PreviewRefusalCode> | TerminalRefusal | ScriptedRefusal | ComputerUseRefusal | SharedWorldRefusal;
288
288
  export type PlanResult = {
@@ -2,13 +2,7 @@ import type { InternalRunLabOptions } from "../run-lab.js";
2
2
  import type { LabDeps } from "./lab-deps.js";
3
3
  import type { PlanResult } from "./plan-types.js";
4
4
  import type { LabConfig } from "./types.js";
5
- /** The five execution paths a lab can take. */
6
- export type LabRoute = "preview" | "computer-use" | "shared-world" | "terminal" | "scripted";
7
- /**
8
- * The route a config takes. It never refuses: a config no route can run still gets the route
9
- * whose own checks refuse it with the most precise reason.
10
- */
11
- export declare function routeOf(config: LabConfig): LabRoute;
5
+ export { routeOf, type LabRoute } from "./routing.js";
12
6
  /** Resolve dry-run: explicit override wins, else the scenario mode, else the given fallback. */
13
7
  export declare function resolveLabDryRun(config: LabConfig, override: boolean | undefined, fallback: boolean | undefined): boolean | undefined;
14
8
  /**
package/dist/lab/plan.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // The route decision. A lab's route follows from its composition (subject.source,
2
- // execution.target, the first actor's registered lane, subject.topology), never from a declared
3
- // kind. This is the only function that decides it.
2
+ // execution.target, the first actor's registered run kind, subject.topology), never from a
3
+ // declared kind. This is the only function that decides it.
4
4
  import { resolveAutomaticAnalysis } from "../analysis/automatic-config.js";
5
5
  import { callerDrivingOf, planComputerUseLab } from "../routes/computer-use/plan.js";
6
6
  import { injectedBrowser, planScriptedLab } from "../routes/scripted/plan.js";
@@ -9,40 +9,9 @@ import { planTerminalLab } from "../routes/terminal/plan.js";
9
9
  import { localBrowserDefaults } from "../substrates/local/runtime-config.js";
10
10
  import { THIS_REPO_DRY_RUN_ONLY } from "./composition-rules.js";
11
11
  import { planBase } from "./plan-base.js";
12
- import { isComputerUseComposition, isScriptedBrowserComposition, isSharedWorldComposition, isTerminalProductComposition, } from "./routing.js";
12
+ import { routeOf } from "./routing.js";
13
13
  import { automaticAnalysisRouteReason, taskProtocolValidationReason } from "./validation.js";
14
- /**
15
- * The route a config takes. It never refuses: a config no route can run still gets the route
16
- * whose own checks refuse it with the most precise reason.
17
- */
18
- export function routeOf(config) {
19
- const source = config.subject.source;
20
- // A scripted-browser actor on a loopback app or a provisioned clone replays committed steps.
21
- if (isScriptedBrowserComposition(config))
22
- return "scripted";
23
- // A terminal-product subject goes to the terminal route even with an unregistered actor, so that
24
- // route refuses the actor instead of another route running something else.
25
- if (isTerminalProductComposition(config) || source === "terminal-product")
26
- return "terminal";
27
- // Checked before computer use: the same composition without the topology declaration runs
28
- // independent participants.
29
- if (isSharedWorldComposition(config))
30
- return "shared-world";
31
- // A CLI studied at a desktop is a computer-use study whose subject is a terminal window.
32
- if (source === "desktop-cli")
33
- return "computer-use";
34
- // Every other app-url, clone, local-app or local-tree config goes to computer use, including
35
- // ones with an unknown actor: that route refuses the actor, where the preview route would run
36
- // no participant at all.
37
- if (isComputerUseComposition(config) ||
38
- source === "app-url" ||
39
- source === "clone" ||
40
- source === "local-app" ||
41
- source === "local-tree")
42
- return "computer-use";
43
- // this-repo runs the synthetic preview.
44
- return "preview";
45
- }
14
+ export { routeOf } from "./routing.js";
46
15
  /** Resolve dry-run: explicit override wins, else the scenario mode, else the given fallback. */
47
16
  export function resolveLabDryRun(config, override, fallback) {
48
17
  if (override !== undefined) {
@@ -66,19 +35,19 @@ function planPreview(config, options, input) {
66
35
  refusal: { route: "preview", code, message },
67
36
  });
68
37
  if (String(config.comms?.email?.kind) === "real")
69
- return refuse("HUMANISH_LAB_COMMS_UNSUPPORTED", "Real email receiving is unsupported on the preview route. Use a supported hosted computer-use lab.");
38
+ return refuse("HUMANISH_STUDY_COMMS_UNSUPPORTED", "Real email receiving is unsupported on the preview route. Use a supported hosted computer-use lab.");
70
39
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
71
40
  if (!analysis.ok)
72
- return refuse("HUMANISH_LAB_ANALYSIS_INVALID", analysis.message);
41
+ return refuse("HUMANISH_STUDY_ANALYSIS_INVALID", analysis.message);
73
42
  const unsupported = automaticAnalysisRouteReason(config);
74
43
  if (unsupported)
75
- return refuse("HUMANISH_LAB_ANALYSIS_UNSUPPORTED", unsupported);
44
+ return refuse("HUMANISH_STUDY_ANALYSIS_UNSUPPORTED", unsupported);
76
45
  const tasksReason = taskProtocolValidationReason(config);
77
46
  if (tasksReason)
78
- return refuse("HUMANISH_LAB_TASKS_UNSUPPORTED", tasksReason);
47
+ return refuse("HUMANISH_STUDY_TASKS_UNSUPPORTED", tasksReason);
79
48
  const participantCount = options.count ?? config.actors[0]?.count ?? 4;
80
49
  if (!Number.isSafeInteger(participantCount) || participantCount < 1)
81
- return refuse("HUMANISH_INVALID_SIM_COUNT", "count must be a positive integer.");
50
+ return refuse("HUMANISH_INVALID_PARTICIPANT_COUNT", "count must be a positive integer.");
82
51
  if (!input.dryRun)
83
52
  return refuse("HUMANISH_LIVE_RUN_UNIMPLEMENTED", THIS_REPO_DRY_RUN_ONLY);
84
53
  return {
@@ -102,7 +71,7 @@ export function planLab(config, options, deps = {}) {
102
71
  const result = planRoute(routeOf(config), lab, options, input, deps);
103
72
  if (!result.ok)
104
73
  return result;
105
- // The manifest the CLI resolved (#455) enters the plan here and nowhere else; the routes read
74
+ // The manifest the CLI resolved enters the plan here and nowhere else; the routes read
106
75
  // plan.lab for the run's status record and bundle.
107
76
  const plan = options.lab === undefined ? result.plan : { ...result.plan, lab: options.lab };
108
77
  return { ok: true, planned: { plan } };