humanish 0.106.1 → 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 (668) hide show
  1. package/ARCHITECTURE.md +38 -32
  2. package/CHANGELOG.md +28 -0
  3. package/CONTEXT.md +51 -41
  4. package/README.md +152 -174
  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-client.js +2 -1
  14. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  15. package/dist/actors/codex/app-server-trace.js +1 -3
  16. package/dist/actors/codex/app-server-ui.js +1 -1
  17. package/dist/actors/codex/app-server.js +2 -1
  18. package/dist/actors/codex/codex-admission.d.ts +91 -0
  19. package/dist/actors/codex/codex-admission.js +150 -0
  20. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  21. package/dist/actors/codex/protocol-compat.js +357 -0
  22. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  23. package/dist/actors/codex/protocol-contract.js +471 -0
  24. package/dist/actors/codex/restricted-executable.d.ts +28 -4
  25. package/dist/actors/codex/restricted-executable.js +104 -29
  26. package/dist/actors/codex/restricted-launch.d.ts +9 -2
  27. package/dist/actors/codex/restricted-launch.js +43 -4
  28. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  29. package/dist/actors/codex/restricted-notifications.js +277 -0
  30. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  31. package/dist/actors/codex/restricted-participant.js +66 -6
  32. package/dist/actors/codex/restricted-policy.d.ts +11 -3
  33. package/dist/actors/codex/restricted-policy.js +2 -2
  34. package/dist/actors/codex/restricted-session.d.ts +16 -3
  35. package/dist/actors/codex/restricted-session.js +60 -22
  36. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  37. package/dist/actors/codex/restricted-transport.js +139 -27
  38. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  39. package/dist/actors/codex/restricted-turn.js +43 -30
  40. package/dist/actors/computer-use/actor.d.ts +17 -17
  41. package/dist/actors/computer-use/actor.js +6 -6
  42. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  43. package/dist/actors/computer-use/admission-limit.js +1 -1
  44. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  45. package/dist/actors/computer-use/loop/actions.js +10 -10
  46. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  47. package/dist/actors/computer-use/loop/backstop.js +15 -13
  48. package/dist/actors/computer-use/loop/ending.d.ts +7 -7
  49. package/dist/actors/computer-use/loop/ending.js +9 -9
  50. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  51. package/dist/actors/computer-use/loop/observation.js +9 -9
  52. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  53. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  54. package/dist/actors/computer-use/loop/session.js +3 -3
  55. package/dist/actors/computer-use/loop/spend.d.ts +2 -2
  56. package/dist/actors/computer-use/loop/spend.js +4 -4
  57. package/dist/actors/computer-use/loop/trace.js +11 -10
  58. package/dist/actors/computer-use/loop/types.d.ts +37 -26
  59. package/dist/actors/computer-use/loop/usage.js +2 -2
  60. package/dist/actors/computer-use/loop.js +4 -4
  61. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  62. package/dist/actors/computer-use/openai-context.js +214 -0
  63. package/dist/actors/computer-use/openai-provider.d.ts +12 -9
  64. package/dist/actors/computer-use/openai-provider.js +47 -36
  65. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  66. package/dist/actors/computer-use/openai-requests.js +82 -15
  67. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  68. package/dist/actors/computer-use/openai-wire.js +36 -34
  69. package/dist/actors/contract.d.ts +86 -49
  70. package/dist/actors/contract.js +29 -23
  71. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  72. package/dist/actors/local-agent/claude-session.js +10 -9
  73. package/dist/actors/local-agent/cli.d.ts +8 -6
  74. package/dist/actors/local-agent/cli.js +24 -28
  75. package/dist/actors/local-agent/readiness.d.ts +2 -2
  76. package/dist/actors/local-agent/readiness.js +4 -4
  77. package/dist/actors/reasoning-effort.js +6 -6
  78. package/dist/actors/registry.d.ts +10 -10
  79. package/dist/actors/registry.js +18 -17
  80. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  81. package/dist/actors/scripted-browser/actor.js +16 -16
  82. package/dist/actors/scripted-browser/browser-command.js +1 -1
  83. package/dist/actors/scripted-browser/journey.js +15 -4
  84. package/dist/actors/scripted-browser/steps.js +19 -1
  85. package/dist/actors/scripted-browser/types.d.ts +12 -2
  86. package/dist/actors/stop-conditions.d.ts +1 -1
  87. package/dist/actors/stop-conditions.js +1 -3
  88. package/dist/analysis/automatic-completion.d.ts +13 -8
  89. package/dist/analysis/automatic-completion.js +14 -8
  90. package/dist/analysis/automatic-config.d.ts +1 -1
  91. package/dist/analysis/automatic-config.js +2 -2
  92. package/dist/analysis/automatic.d.ts +10 -4
  93. package/dist/analysis/automatic.js +17 -13
  94. package/dist/analysis/codex-config.d.ts +6 -2
  95. package/dist/analysis/codex-config.js +22 -14
  96. package/dist/analysis/diagnostics.d.ts +23 -0
  97. package/dist/analysis/diagnostics.js +112 -0
  98. package/dist/analysis/evidence-sources.js +2 -2
  99. package/dist/analysis/evidence.js +6 -6
  100. package/dist/analysis/execute.d.ts +7 -1
  101. package/dist/analysis/execute.js +39 -12
  102. package/dist/analysis/job.d.ts +8 -5
  103. package/dist/analysis/job.js +15 -14
  104. package/dist/analysis/load.d.ts +1 -1
  105. package/dist/analysis/load.js +5 -5
  106. package/dist/analysis/provider.d.ts +9 -1
  107. package/dist/analysis/restricted-codex.d.ts +2 -0
  108. package/dist/analysis/restricted-codex.js +10 -1
  109. package/dist/analysis/service.d.ts +2 -0
  110. package/dist/analysis/service.js +35 -16
  111. package/dist/analysis/sharing.d.ts +2 -2
  112. package/dist/analysis/sharing.js +5 -5
  113. package/dist/analysis/store-executions.d.ts +5 -5
  114. package/dist/analysis/store-executions.js +12 -12
  115. package/dist/analysis/store.d.ts +4 -4
  116. package/dist/analysis/store.js +13 -13
  117. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  118. package/dist/cli/commands/analysis-signals.js +4 -1
  119. package/dist/cli/commands/analyze.js +23 -18
  120. package/dist/cli/commands/codex.js +9 -9
  121. package/dist/cli/commands/comms.js +62 -34
  122. package/dist/cli/commands/feedback.js +20 -21
  123. package/dist/cli/commands/lab-format.d.ts +5 -4
  124. package/dist/cli/commands/lab-format.js +35 -23
  125. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  126. package/dist/cli/commands/lab-route-computer-use.js +32 -21
  127. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  128. package/dist/cli/commands/lab-route-preview.js +7 -7
  129. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  130. package/dist/cli/commands/lab-route-run.js +6 -2
  131. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  132. package/dist/cli/commands/lab-route-scripted.js +0 -1
  133. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  134. package/dist/cli/commands/lab-route-shared-world.js +3 -4
  135. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  136. package/dist/cli/commands/lab-route-terminal.js +0 -1
  137. package/dist/cli/commands/lab-run.js +84 -54
  138. package/dist/cli/commands/lab-scorer.d.ts +2 -4
  139. package/dist/cli/commands/lab-scorer.js +1 -1
  140. package/dist/cli/commands/migrate.d.ts +4 -0
  141. package/dist/cli/commands/migrate.js +65 -0
  142. package/dist/cli/commands/observe.js +168 -107
  143. package/dist/cli/commands/run-command.d.ts +10 -0
  144. package/dist/cli/commands/run-command.js +85 -0
  145. package/dist/cli/commands/run-signals.d.ts +30 -0
  146. package/dist/cli/commands/run-signals.js +146 -0
  147. package/dist/cli/commands/runs.js +137 -136
  148. package/dist/cli/commands/setup.d.ts +2 -2
  149. package/dist/cli/commands/setup.js +26 -21
  150. package/dist/cli/commands/study.d.ts +3 -0
  151. package/dist/cli/commands/study.js +182 -0
  152. package/dist/cli/commands/tui.d.ts +4 -4
  153. package/dist/cli/commands/tui.js +21 -21
  154. package/dist/cli/commands/watch.js +64 -77
  155. package/dist/cli/deprecations.d.ts +18 -0
  156. package/dist/cli/deprecations.js +48 -0
  157. package/dist/cli/doctor.d.ts +18 -5
  158. package/dist/cli/doctor.js +111 -48
  159. package/dist/cli/first-run-path.d.ts +12 -10
  160. package/dist/cli/first-run-path.js +30 -28
  161. package/dist/cli/io.d.ts +46 -10
  162. package/dist/cli/io.js +109 -30
  163. package/dist/cli/observer-follow.d.ts +2 -2
  164. package/dist/cli/observer-follow.js +5 -6
  165. package/dist/cli/orientation.d.ts +6 -3
  166. package/dist/cli/orientation.js +43 -39
  167. package/dist/cli/product-sentence.d.ts +6 -0
  168. package/dist/cli/product-sentence.js +6 -0
  169. package/dist/cli/program.d.ts +6 -1
  170. package/dist/cli/program.js +112 -43
  171. package/dist/cli/telemetry.d.ts +17 -17
  172. package/dist/cli/telemetry.js +49 -41
  173. package/dist/cli.js +1 -1
  174. package/dist/comms/capture-surface.d.ts +14 -13
  175. package/dist/comms/capture-surface.js +23 -22
  176. package/dist/comms/catch-host.d.ts +8 -8
  177. package/dist/comms/catch-host.js +14 -14
  178. package/dist/comms/connections.js +4 -4
  179. package/dist/comms/email-catch.d.ts +3 -3
  180. package/dist/comms/email-catch.js +8 -8
  181. package/dist/comms/external-evidence.d.ts +27 -0
  182. package/dist/comms/external-evidence.js +93 -0
  183. package/dist/comms/extract.js +2 -2
  184. package/dist/comms/fake-inbox.d.ts +2 -2
  185. package/dist/comms/fake-inbox.js +2 -2
  186. package/dist/comms/lease-store.js +7 -7
  187. package/dist/comms/receiving-render.d.ts +1 -1
  188. package/dist/comms/receiving-render.js +2 -2
  189. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  190. package/dist/comms/sandbox-catch-script.js +6 -6
  191. package/dist/comms/sandbox-catch.d.ts +36 -37
  192. package/dist/comms/sandbox-catch.js +34 -35
  193. package/dist/comms/setup.js +42 -8
  194. package/dist/comms/thread-evidence.d.ts +1 -1
  195. package/dist/comms/thread-evidence.js +6 -6
  196. package/dist/comms/types.d.ts +6 -6
  197. package/dist/comms/types.js +4 -4
  198. package/dist/evidence/browser-hygiene.d.ts +1 -1
  199. package/dist/evidence/browser-hygiene.js +1 -1
  200. package/dist/evidence/frame-signature.d.ts +1 -1
  201. package/dist/evidence/frame-signature.js +4 -4
  202. package/dist/evidence/redaction.d.ts +3 -3
  203. package/dist/evidence/redaction.js +5 -5
  204. package/dist/evidence/secret-scrub.d.ts +9 -0
  205. package/dist/evidence/secret-scrub.js +96 -0
  206. package/dist/feedback/draft.js +41 -85
  207. package/dist/feedback/export-bundle.js +5 -5
  208. package/dist/feedback/export.d.ts +5 -1
  209. package/dist/feedback/export.js +16 -17
  210. package/dist/feedback/feedback.d.ts +3 -3
  211. package/dist/feedback/feedback.js +21 -3
  212. package/dist/guest/chromium-text.js +2 -2
  213. package/dist/guest/desktop-native.d.ts +1 -1
  214. package/dist/guest/runtime.js +1 -1
  215. package/dist/index.d.ts +14 -15
  216. package/dist/index.js +10 -11
  217. package/dist/keys/key-resolution.d.ts +7 -5
  218. package/dist/keys/key-resolution.js +40 -38
  219. package/dist/lab/adapter-extension.d.ts +35 -13
  220. package/dist/lab/adapter-extension.js +50 -134
  221. package/dist/lab/adapter-scorer-loader.d.ts +32 -12
  222. package/dist/lab/adapter-scorer-loader.js +56 -32
  223. package/dist/lab/composition-rules.js +58 -58
  224. package/dist/lab/config.js +85 -43
  225. package/dist/lab/deprecated-fields.d.ts +10 -0
  226. package/dist/lab/deprecated-fields.js +24 -0
  227. package/dist/lab/device-presets.d.ts +10 -10
  228. package/dist/lab/device-presets.js +11 -11
  229. package/dist/lab/discover.d.ts +13 -9
  230. package/dist/lab/discover.js +118 -60
  231. package/dist/lab/doctor.d.ts +53 -11
  232. package/dist/lab/doctor.js +193 -47
  233. package/dist/lab/init-plan.js +1 -3
  234. package/dist/lab/init-templates.js +147 -147
  235. package/dist/lab/init.d.ts +1 -1
  236. package/dist/lab/init.js +41 -9
  237. package/dist/lab/keys.d.ts +2 -0
  238. package/dist/lab/keys.js +43 -9
  239. package/dist/lab/lab-deps.d.ts +80 -0
  240. package/dist/lab/lab-deps.js +4 -0
  241. package/dist/lab/parse/actors.js +17 -16
  242. package/dist/lab/parse/comms.js +8 -7
  243. package/dist/lab/parse/execution.js +15 -14
  244. package/dist/lab/parse/study-v3.d.ts +23 -0
  245. package/dist/lab/parse/study-v3.js +259 -0
  246. package/dist/lab/parse/subject-state.d.ts +7 -7
  247. package/dist/lab/parse/subject-state.js +18 -17
  248. package/dist/lab/parse/subject.js +30 -29
  249. package/dist/lab/parse/values.d.ts +1 -2
  250. package/dist/lab/parse/values.js +3 -6
  251. package/dist/lab/persona-resolve.d.ts +7 -7
  252. package/dist/lab/persona-resolve.js +8 -8
  253. package/dist/lab/persona.js +1 -3
  254. package/dist/lab/plan-base.d.ts +0 -2
  255. package/dist/lab/plan-base.js +6 -4
  256. package/dist/lab/plan-participants.d.ts +7 -7
  257. package/dist/lab/plan-participants.js +2 -2
  258. package/dist/lab/plan-types.d.ts +26 -8
  259. package/dist/lab/plan.d.ts +4 -18
  260. package/dist/lab/plan.js +24 -79
  261. package/dist/lab/preflight-probes.js +11 -11
  262. package/dist/lab/preflight-result.d.ts +2 -1
  263. package/dist/lab/preflight-result.js +5 -6
  264. package/dist/lab/preflight.d.ts +7 -8
  265. package/dist/lab/preflight.js +6 -6
  266. package/dist/lab/requirements.d.ts +20 -0
  267. package/dist/lab/requirements.js +54 -0
  268. package/dist/lab/route-inputs.d.ts +23 -12
  269. package/dist/lab/route-inputs.js +48 -51
  270. package/dist/lab/routing.d.ts +42 -41
  271. package/dist/lab/routing.js +66 -68
  272. package/dist/lab/run-lab-events.d.ts +3 -11
  273. package/dist/lab/run-lab-events.js +2 -16
  274. package/dist/lab/run-lab-homes.d.ts +76 -0
  275. package/dist/lab/run-lab-homes.js +7 -0
  276. package/dist/lab/run-lab-options.d.ts +12 -66
  277. package/dist/lab/run-lab-options.js +58 -285
  278. package/dist/lab/summary.d.ts +15 -9
  279. package/dist/lab/summary.js +24 -17
  280. package/dist/lab/tasks.d.ts +15 -15
  281. package/dist/lab/tasks.js +14 -14
  282. package/dist/lab/types.d.ts +201 -195
  283. package/dist/lab/types.js +2 -0
  284. package/dist/lab/validation.d.ts +21 -21
  285. package/dist/lab/validation.js +61 -59
  286. package/dist/lab/warnings.d.ts +10 -0
  287. package/dist/lab/warnings.js +70 -41
  288. package/dist/library-aliases.d.ts +56 -0
  289. package/dist/library-aliases.js +22 -0
  290. package/dist/observer/artifact.d.ts +2 -2
  291. package/dist/observer/artifact.js +9 -9
  292. package/dist/observer/data.d.ts +6 -6
  293. package/dist/observer/data.js +7 -6
  294. package/dist/observer/exposure.d.ts +1 -1
  295. package/dist/observer/exposure.js +11 -11
  296. package/dist/observer/http.js +1 -1
  297. package/dist/observer/library.d.ts +1 -1
  298. package/dist/observer/library.js +4 -2
  299. package/dist/observer/listen.js +5 -4
  300. package/dist/observer/render.d.ts +1 -1
  301. package/dist/observer/render.js +12 -7
  302. package/dist/observer/run-routes.d.ts +4 -4
  303. package/dist/observer/run-routes.js +6 -6
  304. package/dist/observer/serve.d.ts +17 -0
  305. package/dist/observer/serve.js +41 -6
  306. package/dist/observer/tunnel.js +1 -1
  307. package/dist/observer-app.html +4 -4
  308. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  309. package/dist/routes/computer-use/bundle-parts.js +24 -17
  310. package/dist/routes/computer-use/bundle.d.ts +4 -11
  311. package/dist/routes/computer-use/bundle.js +12 -18
  312. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  313. package/dist/routes/computer-use/diagnostics.js +1 -1
  314. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +11 -11
  315. package/dist/routes/computer-use/e2b-desktop/comms.js +24 -27
  316. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  317. package/dist/routes/computer-use/e2b-desktop/desktop.js +8 -11
  318. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +16 -15
  319. package/dist/routes/computer-use/e2b-desktop/fidelity.js +20 -19
  320. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  321. package/dist/routes/computer-use/e2b-desktop/prepare.js +40 -43
  322. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  323. package/dist/routes/computer-use/e2b-desktop/start.js +32 -30
  324. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  325. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  326. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  327. package/dist/routes/computer-use/e2b-desktop/teardown.js +33 -20
  328. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  329. package/dist/routes/computer-use/external-comms.js +19 -43
  330. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  331. package/dist/routes/computer-use/fanout-bundle.js +38 -42
  332. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +33 -28
  333. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  334. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  335. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  336. package/dist/routes/computer-use/live-flush.js +20 -28
  337. package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +4 -2
  338. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +17 -16
  339. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  340. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  341. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  342. package/dist/routes/computer-use/local-vm.js +40 -67
  343. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  344. package/dist/routes/computer-use/participant-desktop.js +5 -25
  345. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +11 -11
  346. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +39 -26
  347. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  348. package/dist/routes/computer-use/participant-facts.js +12 -1
  349. package/dist/routes/computer-use/participant-model.d.ts +25 -11
  350. package/dist/routes/computer-use/participant-model.js +76 -34
  351. package/dist/routes/computer-use/participant-prompt.d.ts +13 -13
  352. package/dist/routes/computer-use/participant-prompt.js +8 -8
  353. package/dist/routes/computer-use/participant-runs.d.ts +11 -11
  354. package/dist/routes/computer-use/participant-runs.js +18 -18
  355. package/dist/routes/computer-use/plan.d.ts +21 -29
  356. package/dist/routes/computer-use/plan.js +70 -78
  357. package/dist/routes/computer-use/preflight.d.ts +3 -5
  358. package/dist/routes/computer-use/preflight.js +40 -36
  359. package/dist/routes/computer-use/rerun-selection.js +11 -7
  360. package/dist/routes/computer-use/result.d.ts +1 -1
  361. package/dist/routes/computer-use/result.js +48 -38
  362. package/dist/routes/computer-use/route.d.ts +5 -5
  363. package/dist/routes/computer-use/route.js +36 -33
  364. package/dist/routes/computer-use/self-report.d.ts +8 -8
  365. package/dist/routes/computer-use/self-report.js +33 -33
  366. package/dist/routes/computer-use/setup.d.ts +9 -15
  367. package/dist/routes/computer-use/setup.js +106 -83
  368. package/dist/routes/computer-use/single-bundle.d.ts +13 -16
  369. package/dist/routes/computer-use/single-bundle.js +46 -53
  370. package/dist/routes/computer-use/subject-projection.d.ts +6 -8
  371. package/dist/routes/computer-use/subject-projection.js +24 -23
  372. package/dist/routes/computer-use/types.d.ts +195 -238
  373. package/dist/routes/computer-use/types.js +21 -13
  374. package/dist/routes/preview.d.ts +8 -2
  375. package/dist/routes/preview.js +8 -5
  376. package/dist/routes/scripted/bundle.d.ts +5 -8
  377. package/dist/routes/scripted/bundle.js +23 -27
  378. package/dist/routes/scripted/plan.d.ts +6 -8
  379. package/dist/routes/scripted/plan.js +15 -13
  380. package/dist/routes/scripted/result.d.ts +4 -1
  381. package/dist/routes/scripted/result.js +15 -11
  382. package/dist/routes/scripted/route.js +15 -17
  383. package/dist/routes/scripted/scenario.d.ts +1 -1
  384. package/dist/routes/scripted/scenario.js +3 -3
  385. package/dist/routes/scripted/setup.d.ts +3 -2
  386. package/dist/routes/scripted/setup.js +27 -26
  387. package/dist/routes/scripted/subject.d.ts +8 -3
  388. package/dist/routes/scripted/subject.js +10 -6
  389. package/dist/routes/scripted/surface-records.js +4 -4
  390. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  391. package/dist/routes/scripted/surface-sessions.js +4 -4
  392. package/dist/routes/scripted/types.d.ts +21 -40
  393. package/dist/routes/scripted/types.js +2 -3
  394. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +17 -16
  395. package/dist/routes/shared-world/bundle.d.ts +7 -7
  396. package/dist/routes/shared-world/bundle.js +60 -62
  397. package/dist/routes/shared-world/checkpoints.d.ts +5 -5
  398. package/dist/routes/shared-world/checkpoints.js +5 -5
  399. package/dist/routes/shared-world/comms.d.ts +8 -7
  400. package/dist/routes/shared-world/comms.js +38 -51
  401. package/dist/routes/shared-world/external-public.d.ts +6 -5
  402. package/dist/routes/shared-world/external-public.js +28 -25
  403. package/dist/routes/shared-world/handoff.d.ts +10 -9
  404. package/dist/routes/shared-world/handoff.js +89 -81
  405. package/dist/routes/shared-world/lobby-code.d.ts +7 -7
  406. package/dist/routes/shared-world/lobby-code.js +22 -22
  407. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +15 -12
  408. package/dist/routes/shared-world/{seats.js → participant-specs.js} +65 -63
  409. package/dist/routes/shared-world/plan.d.ts +2 -6
  410. package/dist/routes/shared-world/plan.js +8 -9
  411. package/dist/routes/shared-world/provenance.d.ts +4 -4
  412. package/dist/routes/shared-world/provenance.js +4 -4
  413. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  414. package/dist/routes/shared-world/provisioned.js +55 -48
  415. package/dist/routes/shared-world/result.js +47 -36
  416. package/dist/routes/shared-world/route.js +54 -57
  417. package/dist/routes/shared-world/setup.d.ts +6 -5
  418. package/dist/routes/shared-world/setup.js +16 -18
  419. package/dist/routes/shared-world/types.d.ts +70 -141
  420. package/dist/routes/shared-world/types.js +5 -5
  421. package/dist/routes/terminal/adapter.d.ts +10 -10
  422. package/dist/routes/terminal/adapter.js +32 -129
  423. package/dist/routes/terminal/bundle.d.ts +10 -15
  424. package/dist/routes/terminal/bundle.js +43 -52
  425. package/dist/routes/terminal/credentials.d.ts +4 -4
  426. package/dist/routes/terminal/credentials.js +20 -20
  427. package/dist/routes/terminal/dry-run.d.ts +1 -1
  428. package/dist/routes/terminal/dry-run.js +13 -15
  429. package/dist/routes/terminal/encoding.d.ts +1 -1
  430. package/dist/routes/terminal/encoding.js +4 -4
  431. package/dist/routes/terminal/ledger.d.ts +8 -8
  432. package/dist/routes/terminal/ledger.js +22 -22
  433. package/dist/routes/terminal/live-finish.d.ts +1 -2
  434. package/dist/routes/terminal/live-finish.js +24 -23
  435. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  436. package/dist/routes/terminal/live-sandbox.js +31 -32
  437. package/dist/routes/terminal/participant-text.d.ts +23 -0
  438. package/dist/routes/terminal/participant-text.js +165 -0
  439. package/dist/routes/terminal/persona.js +1 -1
  440. package/dist/routes/terminal/plan.d.ts +2 -6
  441. package/dist/routes/terminal/plan.js +23 -19
  442. package/dist/routes/terminal/recorder.d.ts +6 -1
  443. package/dist/routes/terminal/recorder.js +12 -4
  444. package/dist/routes/terminal/result.js +12 -12
  445. package/dist/routes/terminal/route.js +30 -31
  446. package/dist/routes/terminal/runtime.d.ts +3 -2
  447. package/dist/routes/terminal/runtime.js +3 -3
  448. package/dist/routes/terminal/sandbox.d.ts +4 -4
  449. package/dist/routes/terminal/sandbox.js +10 -10
  450. package/dist/routes/terminal/session.js +22 -19
  451. package/dist/routes/terminal/token-usage.d.ts +1 -1
  452. package/dist/routes/terminal/token-usage.js +10 -11
  453. package/dist/routes/terminal/trace.d.ts +7 -10
  454. package/dist/routes/terminal/trace.js +11 -66
  455. package/dist/routes/terminal/types.d.ts +104 -114
  456. package/dist/routes/terminal/types.js +12 -7
  457. package/dist/run/active-runs.d.ts +13 -0
  458. package/dist/run/active-runs.js +12 -0
  459. package/dist/run/bundle-shape.d.ts +2 -1
  460. package/dist/run/bundle-shape.js +7 -7
  461. package/dist/run/bundle.d.ts +99 -92
  462. package/dist/run/bundle.js +10 -8
  463. package/dist/run/cost-summary.js +6 -5
  464. package/dist/run/costs.d.ts +6 -6
  465. package/dist/run/costs.js +17 -11
  466. package/dist/run/detail.d.ts +9 -9
  467. package/dist/run/detail.js +10 -10
  468. package/dist/run/dry-run-inputs.js +1 -1
  469. package/dist/run/dry-run.js +23 -30
  470. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  471. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  472. package/dist/run/feedback-shape.js +1 -1
  473. package/dist/run/judge.d.ts +34 -16
  474. package/dist/run/judge.js +41 -14
  475. package/dist/run/locate.d.ts +2 -0
  476. package/dist/run/locate.js +3 -1
  477. package/dist/run/outcomes.d.ts +3 -3
  478. package/dist/run/outcomes.js +3 -3
  479. package/dist/run/participant-records.d.ts +2 -2
  480. package/dist/run/participant-records.js +2 -2
  481. package/dist/run/paths.d.ts +1 -1
  482. package/dist/run/paths.js +2 -2
  483. package/dist/run/pricing.d.ts +30 -15
  484. package/dist/run/pricing.js +49 -30
  485. package/dist/run/projection.d.ts +27 -27
  486. package/dist/run/projection.js +23 -23
  487. package/dist/run/reclaim.d.ts +6 -0
  488. package/dist/run/reclaim.js +15 -5
  489. package/dist/run/results.d.ts +5 -5
  490. package/dist/run/run-index.d.ts +9 -7
  491. package/dist/run/run-index.js +24 -25
  492. package/dist/run/run-not-found.d.ts +5 -0
  493. package/dist/run/run-not-found.js +15 -0
  494. package/dist/run/run.d.ts +7 -4
  495. package/dist/run/run.js +10 -6
  496. package/dist/run/sandbox-receipts.d.ts +5 -5
  497. package/dist/run/sandbox-receipts.js +6 -6
  498. package/dist/run/shared-world-evidence.d.ts +67 -66
  499. package/dist/run/shared-world-evidence.js +4 -4
  500. package/dist/run/shared-world-shape.d.ts +3 -3
  501. package/dist/run/shared-world-shape.js +16 -16
  502. package/dist/run/stats.d.ts +17 -11
  503. package/dist/run/stats.js +124 -66
  504. package/dist/run/status.d.ts +21 -32
  505. package/dist/run/status.js +34 -33
  506. package/dist/run/stored-runs.js +2 -1
  507. package/dist/run/stream-shape.js +1 -1
  508. package/dist/run/streams.d.ts +29 -22
  509. package/dist/run/study-provenance.d.ts +47 -0
  510. package/dist/run/study-provenance.js +63 -0
  511. package/dist/run/study-result.d.ts +16 -0
  512. package/dist/run/study-result.js +9 -0
  513. package/dist/run/terminal-contract.d.ts +5 -5
  514. package/dist/run/terminal-contract.js +4 -4
  515. package/dist/run/text.d.ts +2 -0
  516. package/dist/run/text.js +4 -0
  517. package/dist/run/transient-comms-secrets.d.ts +5 -0
  518. package/dist/run/transient-comms-secrets.js +12 -0
  519. package/dist/run-lab.d.ts +40 -38
  520. package/dist/run-lab.js +42 -40
  521. package/dist/study/convert.d.ts +33 -0
  522. package/dist/study/convert.js +432 -0
  523. package/dist/study/field-paths.d.ts +12 -0
  524. package/dist/study/field-paths.js +126 -0
  525. package/dist/study/files.d.ts +26 -0
  526. package/dist/study/files.js +43 -0
  527. package/dist/study/migrate.d.ts +48 -0
  528. package/dist/study/migrate.js +408 -0
  529. package/dist/study/owned-files.d.ts +38 -0
  530. package/dist/study/owned-files.js +182 -0
  531. package/dist/subject/clone.d.ts +1 -1
  532. package/dist/subject/desktop-cli.d.ts +2 -2
  533. package/dist/subject/desktop-cli.js +3 -3
  534. package/dist/subject/local-tree-archive.d.ts +1 -1
  535. package/dist/subject/local-tree-archive.js +5 -5
  536. package/dist/subject/local-tree.d.ts +3 -3
  537. package/dist/subject/local-tree.js +1 -1
  538. package/dist/subject/node-bootstrap.d.ts +1 -1
  539. package/dist/subject/node-bootstrap.js +4 -4
  540. package/dist/subject/runtime.js +10 -11
  541. package/dist/subject/serve.d.ts +1 -1
  542. package/dist/subject/serve.js +4 -4
  543. package/dist/subject/state.d.ts +1 -1
  544. package/dist/subject/steps.d.ts +8 -8
  545. package/dist/subject/steps.js +7 -7
  546. package/dist/substrates/command-failure.d.ts +3 -3
  547. package/dist/substrates/command-failure.js +3 -3
  548. package/dist/substrates/detached.d.ts +6 -6
  549. package/dist/substrates/detached.js +7 -7
  550. package/dist/substrates/e2b/cdp-probe.d.ts +11 -11
  551. package/dist/substrates/e2b/cdp-probe.js +15 -18
  552. package/dist/substrates/e2b/desktop-browser.d.ts +5 -5
  553. package/dist/substrates/e2b/desktop-browser.js +12 -12
  554. package/dist/substrates/e2b/desktop-cdp.d.ts +15 -15
  555. package/dist/substrates/e2b/desktop-cdp.js +11 -11
  556. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  557. package/dist/substrates/e2b/desktop-executor.js +1 -1
  558. package/dist/substrates/e2b/desktop-geometry.d.ts +6 -6
  559. package/dist/substrates/e2b/desktop-geometry.js +9 -9
  560. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  561. package/dist/substrates/e2b/desktop-media.js +3 -3
  562. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  563. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  564. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  565. package/dist/substrates/e2b/sandbox.js +2 -2
  566. package/dist/substrates/e2b/sdk.d.ts +11 -11
  567. package/dist/substrates/e2b/sdk.js +8 -8
  568. package/dist/substrates/local/runtime-host.d.ts +2 -0
  569. package/dist/substrates/local/runtime-host.js +6 -0
  570. package/dist/tui/actions.d.ts +8 -6
  571. package/dist/tui/actions.js +31 -22
  572. package/dist/tui/contract.d.ts +16 -16
  573. package/dist/tui/contract.js +10 -10
  574. package/dist/tui/launch.d.ts +4 -4
  575. package/dist/tui/launch.js +18 -19
  576. package/dist/tui/project.js +5 -5
  577. package/dist/tui-app.js +83 -83
  578. package/dist/verify/actor.d.ts +14 -14
  579. package/dist/verify/actor.js +45 -45
  580. package/dist/verify/artifacts.d.ts +3 -3
  581. package/dist/verify/artifacts.js +6 -6
  582. package/dist/verify/context-growth.d.ts +9 -0
  583. package/dist/verify/context-growth.js +62 -0
  584. package/dist/verify/costs.d.ts +7 -7
  585. package/dist/verify/costs.js +9 -9
  586. package/dist/verify/liveness.d.ts +1 -1
  587. package/dist/verify/liveness.js +4 -1
  588. package/dist/verify/rerun.d.ts +1 -1
  589. package/dist/verify/rerun.js +1 -1
  590. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  591. package/dist/verify/shared-world-concurrent.js +79 -76
  592. package/dist/verify/shared-world.d.ts +2 -2
  593. package/dist/verify/shared-world.js +18 -18
  594. package/dist/verify/subject.d.ts +4 -4
  595. package/dist/verify/subject.js +18 -18
  596. package/dist/verify/verify.js +98 -49
  597. package/docs/README.md +26 -33
  598. package/docs/architecture/actor-contract.md +105 -98
  599. package/docs/architecture/desktop-sessions.md +14 -14
  600. package/docs/architecture/external-public-shared-world.md +66 -59
  601. package/docs/architecture/github-feedback-loop.md +1 -4
  602. package/docs/architecture/guest-desktop.md +2 -2
  603. package/docs/architecture/observer.md +37 -37
  604. package/docs/architecture/restricted-codex-analysis.md +70 -30
  605. package/docs/architecture/serve.md +34 -37
  606. package/docs/architecture/state-driven-executor.md +55 -59
  607. package/docs/architecture/task-protocol-support.md +7 -9
  608. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +83 -115
  609. package/docs/contracts/README.md +24 -0
  610. package/docs/contracts/adapter-admission.md +3 -3
  611. package/docs/contracts/adapter-fixtures.md +2 -5
  612. package/docs/contracts/core.md +1 -3
  613. package/docs/contracts/errors.md +62 -0
  614. package/docs/contracts/feedback.md +8 -9
  615. package/docs/contracts/policy.md +7 -12
  616. package/docs/contracts/run-bundle.md +54 -51
  617. package/docs/contracts/schemas.md +505 -390
  618. package/docs/contracts/study-analysis.md +26 -2
  619. package/docs/contracts/study-costs.md +11 -7
  620. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  621. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  622. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  623. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  624. package/docs/principles/actor-fidelity.md +4 -4
  625. package/docs/principles/engineering.md +3 -3
  626. package/docs/principles/invariants-and-defaults.md +38 -38
  627. package/docs/principles/self-driving-harness.md +1 -5
  628. package/docs/principles/three-roles.md +1 -1
  629. package/docs/product/automatic-analysis.md +8 -7
  630. package/examples/participant/README.md +5 -5
  631. package/examples/participant/run.mjs +11 -10
  632. package/examples/scorer/README.md +3 -3
  633. package/examples/scorer/run.mjs +11 -12
  634. package/package.json +16 -17
  635. package/skills/humanish/SKILL.md +63 -60
  636. package/skills/humanish/agents/openai.yaml +1 -1
  637. package/AGENTS.md +0 -99
  638. package/CONTRIBUTING.md +0 -148
  639. package/dist/actors/codex/qualified-versions.d.ts +0 -45
  640. package/dist/actors/codex/qualified-versions.js +0 -87
  641. package/dist/cli/commands/lab.d.ts +0 -3
  642. package/dist/cli/commands/lab.js +0 -193
  643. package/dist/deprecated.d.ts +0 -90
  644. package/dist/deprecated.js +0 -106
  645. package/dist/lab/bag-overrides.d.ts +0 -18
  646. package/dist/lab/bag-overrides.js +0 -121
  647. package/dist/observer/static.d.ts +0 -39
  648. package/dist/observer/static.js +0 -369
  649. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  650. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  651. package/docs/architecture/comms-inbox.md +0 -122
  652. package/docs/architecture/desktop-recording.md +0 -80
  653. package/docs/architecture/local-browser-runtime.md +0 -178
  654. package/docs/architecture/observer-review.md +0 -144
  655. package/docs/architecture/participant-media.md +0 -90
  656. package/docs/architecture/project-layout.md +0 -62
  657. package/docs/architecture/real-email-receiving.md +0 -136
  658. package/docs/assets/humanish-drawdb-hero.png +0 -0
  659. package/docs/assets/humanish-observer-hero.png +0 -0
  660. package/docs/goals/current.md +0 -207
  661. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  662. package/docs/product/open-source-install-experience.md +0 -240
  663. package/docs/ramp/README.md +0 -294
  664. package/docs/release/open-source-readiness.md +0 -222
  665. package/docs/release/public-readiness-standard.md +0 -210
  666. package/docs/roadmap/world-class-open-source-v0.md +0 -311
  667. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  668. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -4,29 +4,30 @@ export const DEFAULT_LOCAL_BROWSER_STARTER = {
4
4
  };
5
5
  function localBrowserLab(starter = DEFAULT_LOCAL_BROWSER_STARTER) {
6
6
  return {
7
- path: "humanish/labs/local-browser.yaml",
7
+ path: "humanish/studies/local-browser.yaml",
8
8
  plane: "source",
9
- contents: `schema: humanish.lab.v2
9
+ contents: `schema: humanish.study.v3
10
10
  id: local-browser
11
11
  title: Local browser · your app · Codex account
12
12
  description: >-
13
- Run a Codex-account participant in an isolated local browser against your loopback app—no E2B
14
- or OpenAI API key. Inference is remote and uses account quota. Before the first live run, use
15
- humanish doctor --lab local-browser to check the supported Codex login and local runtime.
13
+ Runs one participant on your Codex account in an isolated local browser against your loopback
14
+ app. Needs no E2B or OpenAI API key: inference is remote and uses your Codex account quota.
15
+ Before the first live run, check the Codex login and the local runtime with humanish doctor
16
+ --study local-browser.
17
+ route: computer-use
18
+ mode: live
16
19
  subject:
17
20
  source: app-url
18
21
  appUrl: ${JSON.stringify(starter.appUrl)}
19
- actors:
20
- - type: local-agent
21
- localAgent: codex
22
- persona: synthetic-new-user
23
- mission: ${JSON.stringify(starter.mission)}
22
+ actor:
23
+ type: local-agent
24
+ localAgent: codex
25
+ persona: synthetic-new-user
26
+ mission: ${JSON.stringify(starter.mission)}
24
27
  execution:
25
28
  target: local
26
29
  concurrency: 1
27
30
  timeoutMs: 120000
28
- scenario:
29
- mode: live
30
31
  defaults:
31
32
  open: true
32
33
  `,
@@ -34,51 +35,53 @@ defaults:
34
35
  }
35
36
  /**
36
37
  * The flagship live lab. A ChatGPT-account Codex participant has no API-dollar price, so preflight
37
- * refuses a dollar cap on it (HUMANISH_CUA_LAB_UNPRICED_CAP); that variant is bounded by the
38
+ * refuses a dollar cap on it (HUMANISH_COMPUTER_USE_UNPRICED_CAP); that variant is bounded by the
38
39
  * session timeout instead of a cap it could never enforce.
39
40
  */
40
41
  function tryLiveLab(actor, localAgent = "codex") {
41
42
  const account = actor === "local-agent";
42
- const cost = account
43
- ? ` WHAT IT COSTS: one participant, one small task, a few E2B desktop minutes and your Codex
44
- account's usage. Account usage has no dollar price humanish can enforce, so the ten-minute
45
- session limit below bounds the run.`
46
- : ` WHAT IT COSTS: one participant, one small task, and a $2 cap on estimated model spend. The
47
- run stops before its next model request once the estimate passes $2, so the last request can take
48
- it slightly over. Hosted desktop time is billed separately.`;
43
+ const needs = account
44
+ ? ` Needs E2B_API_KEY and the coding agent signed in on this machine. Cost: one small task, a few
45
+ E2B desktop minutes and the agent's account usage. humanish cannot put a dollar cap on account
46
+ usage, so the ten-minute session limit below bounds the run.`
47
+ : ` Needs E2B_API_KEY and OPENAI_API_KEY. Cost: one small task with a $2 cap on estimated model
48
+ spend. The run stops before its next model request once the estimate passes $2, so the last
49
+ request can go slightly over, and hosted desktop time is billed separately.`;
49
50
  const participant = account
50
- ? ` # Your machine has a coding agent signed in, so this lab uses it: no provider API key,
51
- # only E2B. To use a provider key instead, swap to \`type: openai-computer-use\` and add
52
- # execution.caps.maxUsd.
53
- - type: local-agent
54
- localAgent: ${localAgent}`
55
- : ` - type: openai-computer-use
56
- # Bounds each model reply. Under the cap below it also bounds what a stalled or lost request
57
- # can cost, so the run can retry it instead of stopping.
58
- maxOutputTokens: 8192`;
59
- const bound = account
51
+ ? `# Your machine has a coding agent signed in, so this study uses it: no provider API key, only
52
+ # E2B. To use a provider key instead, swap to \`type: openai-computer-use\` and add caps.maxUsd.
53
+ actor:
54
+ type: local-agent
55
+ localAgent: ${localAgent}`
56
+ : `actor:
57
+ type: openai-computer-use
58
+ # Bounds each model reply. Under the cap below it also bounds what a stalled or lost request
59
+ # can cost, so the run can retry it instead of stopping.
60
+ maxOutputTokens: 8192`;
61
+ const caps = account
62
+ ? ""
63
+ : `caps:
64
+ maxUsd: 2 # estimated model spend; the run stops before its next request once it passes this
65
+ `;
66
+ const timeout = account
60
67
  ? " timeoutMs: 600000 # bounds the run; a dollar cap cannot be enforced on account usage"
61
- : ` timeoutMs: 600000
62
- caps:
63
- maxUsd: 2 # estimated model spend; the run stops before its next request once it passes this`;
68
+ : " timeoutMs: 600000";
64
69
  return {
65
- path: "humanish/labs/try-live.yaml",
70
+ path: "humanish/studies/try-live.yaml",
66
71
  plane: "source",
67
- contents: `schema: humanish.lab.v2
72
+ contents: `schema: humanish.study.v3
68
73
  id: try-live
69
- title: Your first REAL study — one participant, a real app, a hosted desktop
74
+ title: "Your first live study: one participant on a demo app"
70
75
  description: >-
71
- This lab runs live out of the box, on purpose. Every other starter file here is a template you
72
- have to fill in first, and a first live run that cannot succeed is where most people stop.
73
- THE SUBJECT IS A DEMO, NOT YOUR APP: it clones drawDB, a real public open-source diagram editor,
74
- and serves it inside the sandbox. That is what makes this runnable with nothing to configure.
75
- Once you have watched it work, point subject at your own app (see humanish/labs/cua-browser.yaml
76
- for the shape) — that is the study you actually want.
77
- ${cost}
78
- WHAT A GOOD RESULT LOOKS LIKE: not necessarily a pass. A participant who gets stuck and says so
79
- is the most useful thing this tool produces — humanish will refuse to call that a credible pass,
80
- on purpose, and the friction they describe is the finding. A first run that ends in "I could not
81
- do it, and here is where I got lost" worked exactly as intended.
76
+ Runs one participant live on drawDB, a public open-source diagram editor that humanish clones
77
+ and serves in a hosted desktop, so it runs with nothing to configure. The app under study is
78
+ that demo, not yours. The other starter studies need your app's details first.
79
+ ${needs}
80
+ A participant who gets stuck and says where is a useful result: humanish does not count that
81
+ run as a pass, and the friction the participant describes is the finding. To study your own
82
+ app, change subject; humanish/studies/cua-browser.yaml shows the shape.
83
+ route: computer-use
84
+ mode: live # the other starter studies start as dry runs
82
85
  subject:
83
86
  source: clone
84
87
  repos:
@@ -86,22 +89,19 @@ subject:
86
89
  clone:
87
90
  depth: 1
88
91
  serve:
89
- # Plain npm — humanish provides the Node runtime the stock desktop image does not ship.
92
+ # Plain npm: humanish provides the Node runtime that the stock desktop image lacks.
90
93
  install: npm install --no-audit --no-fund
91
94
  build: npm run build
92
95
  start: npx vite preview --host 127.0.0.1 --port 3000
93
96
  url: http://127.0.0.1:3000/
94
- actors:
95
97
  ${participant}
96
- persona: synthetic-new-user
97
- mission: >-
98
- You have never seen this diagram tool before. Add two tables and give them meaningful names,
99
- then stop and say what you did, what confused you, and where you hesitated.
100
- execution:
98
+ persona: synthetic-new-user
99
+ mission: >-
100
+ You have never seen this diagram tool before. Add two tables and give them meaningful names,
101
+ then stop and say what you did, what confused you, and where you hesitated.
102
+ ${caps}execution:
101
103
  target: e2b-desktop
102
- ${bound}
103
- scenario:
104
- mode: live # the point of this lab — the others start as dry-run
104
+ ${timeout}
105
105
  defaults:
106
106
  open: true
107
107
  `,
@@ -113,7 +113,8 @@ export const starterFiles = [
113
113
  plane: "source",
114
114
  contents: `# humanish
115
115
 
116
- This directory is the committed source of persona simulation intent for this app.
116
+ This directory holds the committed definitions of this app's humanish studies: study files,
117
+ personas and scenarios.
117
118
 
118
119
  Keep this directory public-safe:
119
120
 
@@ -124,11 +125,13 @@ Keep this directory public-safe:
124
125
 
125
126
  Generated run bundles, screenshots, traces, logs, and local overrides belong in ignored \`.humanish/\`.
126
127
 
127
- Labs:
128
+ Studies:
128
129
 
129
- - committed reusable labs live in humanish/labs/*.yaml;
130
- - private or machine-local labs live in ignored .humanish/labs/*.yaml or .humanish/local/labs/*.yaml;
131
- - run a lab with \`humanish watch <lab>\` or \`humanish lab run <lab>\`.
130
+ - committed reusable studies live in humanish/studies/*.yaml;
131
+ - private or machine-local studies live in ignored .humanish/studies/*.yaml or
132
+ .humanish/local/studies/*.yaml;
133
+ - run a study with \`humanish run <study>\`, or \`humanish watch <study>\` to stay attached;
134
+ - files under humanish/labs/ move there with \`humanish migrate\`.
132
135
 
133
136
  Format standard:
134
137
 
@@ -207,19 +210,21 @@ steps:
207
210
  `,
208
211
  },
209
212
  {
210
- path: "humanish/labs/first-run.yaml",
213
+ path: "humanish/studies/first-run.yaml",
211
214
  plane: "source",
212
- contents: `schema: humanish.lab.v2
215
+ contents: `schema: humanish.study.v3
213
216
  id: first-run
214
217
  title: First-run synthetic Observer
215
- description: Public-safe starter lab that generates a synthetic run bundle and Observer without provider spend.
218
+ description: >-
219
+ Does a dry run: writes a synthetic run bundle and Observer for four participants. Needs no browser,
220
+ model or keys, and costs nothing. Run it with humanish run first-run.
221
+ route: preview
222
+ mode: dry-run
216
223
  subject:
217
224
  source: this-repo
218
- actors:
219
- - type: synthetic-persona
220
- count: 4
221
- scenario:
222
- mode: dry-run
225
+ actor:
226
+ type: synthetic-persona
227
+ participants: 4
223
228
  defaults:
224
229
  open: true
225
230
  `,
@@ -227,19 +232,21 @@ defaults:
227
232
  tryLiveLab("openai-computer-use"),
228
233
  localBrowserLab(),
229
234
  {
230
- path: "humanish/labs/cua-browser.yaml",
235
+ path: "humanish/studies/cua-browser.yaml",
231
236
  plane: "source",
232
- contents: `schema: humanish.lab.v2
237
+ contents: `schema: humanish.study.v3
233
238
  id: cua-browser
234
- title: Computer-use browser lab
239
+ title: Computer-use browser study
235
240
  description: >-
236
- A registered computer-use actor drives your app in a hosted desktop browser and emits an
237
- evidence bundle into gitignored .humanish/. Screenshots are full-fidelity (raw) by default;
238
- set policies.redactScreenshots: true to blur at capture for a share-as-is bundle. Typed
239
- text is recorded as length only. Dry-run by default; switch scenario.mode to live (with
240
- OPENAI_API_KEY + E2B_API_KEY via --env-file) for a real session. The clone subject below
241
- serves your repo INSIDE the sandbox; declared subject env NAMES are provisioned from
242
- --env-file (values are never persisted).
241
+ A computer-use participant drives your app in a hosted desktop browser and writes its evidence
242
+ to gitignored .humanish/. Starts as a dry run. For a live session, set mode to live
243
+ and pass OPENAI_API_KEY and E2B_API_KEY with --env-file. The clone subject below serves your
244
+ repo inside the sandbox, and the env names declared under subject get their values from
245
+ --env-file without the values being saved. Screenshots keep full fidelity by default; set
246
+ policies.redactScreenshots: true to blur them at capture for a bundle you can share as is.
247
+ Typed text is recorded as its length only.
248
+ route: computer-use
249
+ mode: dry-run
243
250
  subject:
244
251
  source: clone
245
252
  repos: [your-org/your-app]
@@ -251,7 +258,7 @@ subject:
251
258
  # installTimeoutMs: 1200000 # bump for monorepo-scale installs/builds (default 600000)
252
259
  # buildTimeoutMs: 1800000
253
260
  # env: [DATABASE_URL]
254
- # state: # the subject's STATE story (recorded as provenance):
261
+ # state: # the subject's state, recorded as provenance:
255
262
  # seed: # ordered, bounded seed/migration/fixture steps (commands are
256
263
  # - name: db-up # author-trusted; evidence records sha256 digests, never text)
257
264
  # command: sudo service postgresql start && pg_isready -t 30
@@ -259,104 +266,97 @@ subject:
259
266
  # - name: db-migrate
260
267
  # command: pnpm prisma migrate deploy
261
268
  # timeoutMs: 300000 # per-step budget (default 300000)
262
- # - name: admin-user # after-ready steps run against the RUNNING app
269
+ # - name: admin-user # after-ready steps run against the running app
263
270
  # command: curl -sf -X POST http://127.0.0.1:3000/api/test/bootstrap-admin
264
271
  # when: after-ready
265
- # # Or point at a shared DB you do NOT control — recorded as UNPINNED in provenance;
272
+ # # Or point at a shared DB you do not control; provenance records it as unpinned.
266
273
  # # each name must also be declared in subject.env:
267
274
  # # external: [DATABASE_URL]
268
275
  # clone:
269
- # keep: true # leave the sandbox up on FAILURE so you can debug install/boot
276
+ # keep: true # keep the sandbox after a failure to debug install or boot
270
277
  # Alternative: drive a deployment you own (Vercel preview, staging) instead of a clone:
271
278
  # source: app-url
272
279
  # appUrl: https://your-preview.vercel.app/
273
- actors:
274
- - type: openai-computer-use
275
- persona: first-time-visitor
276
- mission: >-
277
- Explore the app as a brand-new user trying to complete its primary flow. Note anything
278
- confusing. Stop when the flow completes or you are stuck.
280
+ actor:
281
+ type: openai-computer-use
282
+ persona: synthetic-new-user
283
+ mission: >-
284
+ Explore the app as a brand-new user trying to complete its primary flow. Note anything
285
+ confusing. Stop when the flow completes or you are stuck.
279
286
  execution:
280
287
  target: e2b-desktop
281
- # 20 minutes: a session should end because the participant finished, not because a timer fired,
282
- # so this is as long as the substrate allows rather than as long as seems reasonable. This route
283
- # clones, installs, builds and serves the subject before the actor starts, so the sandbox deadline
284
- # is this budget PLUS 40 minutes of provisioning and teardown headroom — and a sandbox may not
285
- # live longer than 60. Raising this above 20 minutes fails the run closed before it starts; raise
286
- # execution.desktop.sandboxTimeoutMs deliberately if you need more.
287
- # Spend protection belongs to the dollar caps, not the clock.
288
+ # 20 minutes, the longest this route allows, so a session ends when the participant finishes.
289
+ # The route clones, installs, builds and serves the subject before the participant starts, so
290
+ # the sandbox deadline is this budget plus 40 minutes of provisioning and teardown, and a sandbox
291
+ # lives at most 60 minutes. A value above 20 minutes fails the run before it starts; raise
292
+ # execution.desktop.sandboxTimeoutMs if you need more. The dollar caps limit spend.
288
293
  timeoutMs: 1200000
289
294
  desktop:
290
295
  device: desktop # mobile | small-mobile | narrow-mobile | tablet | desktop | wide
291
296
  # browser: chrome # default | chrome | chromium | firefox; concrete values fail closed
292
297
  # Presets size the physical screen; Chrome's window width has a ~500px minimum.
293
298
  # For mobile presets, opt into CSS viewport, touch, DPR and mobile user-agent emulation:
294
- # fidelity: { mobileEmulation: true } # Chrome/Chromium only; desktop/tablet lanes unchanged
299
+ # fidelity: { mobileEmulation: true } # Chrome/Chromium only; desktop and tablet are unchanged
295
300
  # The bundle records measured screen, page viewport and emulation fidelity separately.
296
- scenario:
297
- mode: dry-run
298
301
  # policies:
299
- # redactScreenshots: true # blur persisted frames (default off — full fidelity for local use)
302
+ # redactScreenshots: true # blur saved frames (off by default: full fidelity for local use)
300
303
  # allowPublicTargets: true # required to drive a non-loopback app-url (a deployment you own)
301
304
  defaults:
302
305
  open: true
303
306
  `,
304
307
  },
305
308
  {
306
- path: "humanish/labs/lobby-trivia-3player.yaml",
309
+ path: "humanish/studies/lobby-trivia-3player.yaml",
307
310
  plane: "source",
308
- contents: `schema: humanish.lab.v2
311
+ contents: `schema: humanish.study.v3
309
312
  id: lobby-trivia-3player
310
- title: External-public shared world (N mobile personas share ONE public app at once)
313
+ title: "Shared world on a public app: three mobile participants in one lobby"
311
314
  description: >-
312
- A worked example of the EXTERNAL-PUBLIC shared-world route (#164 phase 2): N mobile-LAYOUT
313
- personas play the SAME multiplayer lobby on a REAL public deployment AT ONCE. The public site is
314
- the shared plane DIRECTLY — NO clone, NO getHost, NO subject sandbox, NO seed. A host-first barrier
315
- extracts the shared-session code from the host seat's CDP-observed URL and threads it into the
316
- follower join missions (followers go through the real Join flow). Dry-run (the default) emits ONE
317
- external-public evidence bundle at $0. A live run needs OPENAI_API_KEY + E2B_API_KEY and
318
- scenario.mode: live. Point appUrl + publicTarget at a public deployment YOU own/operate.
319
- MOBILE FIDELITY: by default Chrome's physical window has a 500px minimum width, no touch
320
- emulation and desktop DPR/user-agent behavior. Set execution.desktop.fidelity.mobileEmulation to true
321
- to request the mobile preset's CSS viewport, touch, DPR and mobile user agent on Chrome/Chromium.
322
- The bundle records measured geometry and emulation fidelity. HONESTY: attribution stays
323
- shared-world, but every strength claim degrades honestly — provenance external-public (not seeded),
324
- NO synthetic attestation (you cannot claim synthetic on a real site), NO authoritative shared-state
325
- proof, concurrency by temporal co-occupancy + observed lobby convergence.
315
+ A worked example of the external-public shared-world route: three participants on mobile layouts
316
+ play the same multiplayer lobby on a public deployment at the same time. The public site is the
317
+ shared plane, so there is no clone, subject sandbox or seed. The host participant creates the
318
+ lobby, humanish reads the session code from the host's page URL, and the other participants get
319
+ it in their missions and join through the app's own join flow. Starts as a dry run, which writes
320
+ one evidence bundle at no cost. A live run needs OPENAI_API_KEY, E2B_API_KEY and mode: live. Point appUrl and publicTarget at a public deployment you own or operate. Mobile layout:
321
+ Chrome's physical window is at least 500px wide and has no touch emulation, desktop pixel ratio
322
+ and a desktop user agent. Set execution.desktop.fidelity.mobileEmulation to true to request the
323
+ preset's CSS viewport, touch, pixel ratio and mobile user agent on Chrome or Chromium; the bundle
324
+ records the measured geometry and emulation fidelity. A run on a public site proves less than a
325
+ provisioned one: its provenance is external-public, it carries no synthetic-data attestation and
326
+ no authoritative shared-state proof, and concurrency rests on overlapping sessions and every
327
+ participant reaching the same lobby.
328
+ route: shared-world
329
+ mode: dry-run # a live run opens three mobile-layout desktops against the public app
326
330
  subject:
327
- source: app-url # the real public deployment IS the shared plane (no clone, no getHost)
328
- topology: shared-world # the declared override of the per-lane-worlds default
329
- appUrl: https://your-public-app.example/ # a deployment YOU own/operate
330
- publicTarget: # REQUIRED ownership attestation (the honest analog of exposure: synthetic)
331
+ source: app-url # the public deployment is the shared plane: no clone and no getHost
332
+ appUrl: https://your-public-app.example/ # a deployment you own or operate
333
+ publicTarget: # required: your attestation that you own or operate this deployment
331
334
  owner: your-org/your-app
332
335
  authorized: true
333
336
  policies:
334
- allowPublicTargets: true # REQUIRED: the shared plane is a real non-loopback public deployment
335
- actors:
336
- - type: openai-computer-use
337
- mission: You are one of several users on the same shared session at once. Play your role, then stop.
338
- lanes: # the roster (>=2) with EXACTLY ONE host: true seat
339
- - id: host
340
- host: true # the designated host seat that creates the shared session
341
- device: mobile # 414x896 preset; physical window width floors to 500 (see emulation above)
342
- instruction: Create a shared lobby, wait for the others to join, then start and play.
343
- - id: player-2
344
- device: mobile
345
- instruction: Join the lobby you're told the code for, then play.
346
- - id: player-3
347
- device: small-mobile
348
- instruction: Join the lobby you're told the code for, then play.
337
+ allowPublicTargets: true # required: the shared plane is a public, non-loopback deployment
338
+ actor:
339
+ type: openai-computer-use
340
+ mission: You are one of several users on the same shared session at once. Play your role, then stop.
341
+ participants: # at least two participants, exactly one with host: true
342
+ - id: host
343
+ host: true # this participant creates the shared session
344
+ device: mobile # 414x896 preset; physical window width floors to 500 (see emulation above)
345
+ instruction: Create a shared lobby, wait for the others to join, then start and play.
346
+ - id: player-2
347
+ device: mobile
348
+ instruction: Join the lobby you're told the code for, then play.
349
+ - id: player-3
350
+ device: small-mobile
351
+ instruction: Join the lobby you're told the code for, then play.
349
352
  execution:
350
353
  target: e2b-desktop
351
- # PER-SEAT session budget; also caps the host-first handoff deadline. Budget for the WHOLE arc:
352
- # seat provisioning + shared-session assembly + actual play. A first live run of the worked
353
- # example died at 120000 with every seat expiring mid game and zero mission actions taken.
354
+ # Each participant's session budget, which also bounds the host's handoff deadline. It has to
355
+ # cover provisioning, joining the shared session and play; 420000 ms (7 minutes) does.
354
356
  timeoutMs: 420000
355
- concurrency: 3 # all 3 seats live at once (the default when omitted); lower only to cap paid desktops
357
+ concurrency: 3 # all three participants at once, the default; lower it only to limit paid desktops
356
358
  # desktop:
357
359
  # fidelity: { mobileEmulation: true } # opt into mobile CSS viewport, touch, DPR and user agent
358
- scenario:
359
- mode: dry-run # default; the live path opens N real mobile-layout seats against the public app
360
360
  defaults:
361
361
  open: true
362
362
  `,
@@ -388,8 +388,8 @@ export const runtimeDirectories = [
388
388
  { path: ".humanish/cache", plane: "runtime" },
389
389
  { path: ".humanish/tmp", plane: "runtime" },
390
390
  { path: ".humanish/logs", plane: "runtime" },
391
- { path: ".humanish/labs", plane: "runtime" },
392
- { path: ".humanish/local/labs", plane: "runtime" },
391
+ { path: ".humanish/studies", plane: "runtime" },
392
+ { path: ".humanish/local/studies", plane: "runtime" },
393
393
  { path: ".humanish/local/personas", plane: "runtime" },
394
394
  ];
395
395
  export const humanishScripts = {
@@ -408,9 +408,9 @@ export const humanishScripts = {
408
408
  * only E2B. Writing the other one there would hand someone homework instead of a first run.
409
409
  */
410
410
  export function starterFilesFor(actor, localBrowser = DEFAULT_LOCAL_BROWSER_STARTER, localAgent) {
411
- return starterFiles.map((file) => file.path === "humanish/labs/local-browser.yaml"
411
+ return starterFiles.map((file) => file.path === "humanish/studies/local-browser.yaml"
412
412
  ? localBrowserLab(localBrowser)
413
- : file.path === "humanish/labs/try-live.yaml"
413
+ : file.path === "humanish/studies/try-live.yaml"
414
414
  ? tryLiveLab(actor, localAgent)
415
415
  : file);
416
416
  }
@@ -26,7 +26,7 @@ export interface InitResult {
26
26
  changes: InitChange[];
27
27
  warnings: string[];
28
28
  /**
29
- * The next one or two commands, already resolved against THIS machine's credentials. Present on
29
+ * The next one or two commands, already resolved against this machine's credentials. Present on
30
30
  * an applied init; absent on a dry-run or a failure, where there is no "next" yet.
31
31
  */
32
32
  nextSteps?: string[];
package/dist/lab/init.js CHANGED
@@ -8,6 +8,7 @@ import { assertPreparedSelectedOutputDirectory, prepareContainedOutputDirectory,
8
8
  import { validateCwd } from "../run/project.js";
9
9
  import { pathExists, readTextIfExists, validateInitProjectPaths } from "./init-paths.js";
10
10
  import { planGitignore, planPackageJson } from "./init-plan.js";
11
+ import { otherStudyFiles, STUDY_DIRECTORIES, studyFileStem } from "../study/files.js";
11
12
  const INIT_RESPONSE_SCHEMA = "humanish.init-result.v1";
12
13
  export async function runInit(options) {
13
14
  const requestedCwd = path.resolve(options.cwd);
@@ -39,7 +40,7 @@ export async function runInit(options) {
39
40
  await planAgentsFile(preparedProjectRoot, cwd, plan);
40
41
  // The starter live lab is written for the brain this machine can actually use. Shipping it as
41
42
  // openai-computer-use on a machine with no provider key but a signed-in Codex would hand someone
42
- // a file that asks for a credential they were just told they do not need (#505).
43
+ // a file that asks for a credential they were just told they do not need.
43
44
  const machine = await firstRunEnvironment(options.env ?? process.env, requestedCwd);
44
45
  const starterActor = starterActorFor(machine);
45
46
  await planStarterFiles(preparedProjectRoot, cwd, starterFilesFor(starterActor, localBrowser.value, starterLocalAgentFor(machine)), options.localBrowser !== undefined, plan);
@@ -77,16 +78,16 @@ export async function runInit(options) {
77
78
  cwd: requestedCwd,
78
79
  changes: plan.changes,
79
80
  warnings: plan.warnings,
80
- // Resolved against THIS machine, because a next step that cannot work is worse than none.
81
+ // Resolved against this machine, because a next step that cannot work is worse than none.
81
82
  ...(mode === "applied" ? { nextSteps: firstRunGuidance(machine) } : {}),
82
83
  };
83
84
  }
84
- // Leave instructions for the NEXT agent. AGENTS.md is the cross-vendor convention (agents.md) —
85
- // Codex, Claude Code, Cursor, Aider and others read it — and increasingly the thing that runs
85
+ // Leave instructions for the next agent. `AGENTS.md` is the cross-vendor convention (agents.md);
86
+ // Codex, Claude Code, Cursor, Aider and others read it, and increasingly the thing that runs
86
87
  // `humanish init` is a coding agent doing setup on someone's behalf. Without this, the agent
87
88
  // that arrives tomorrow finds a humanish/ directory and no idea what to do with it.
88
89
  //
89
- // APPEND-ONLY and idempotent: an existing AGENTS.md is a file someone wrote, so humanish adds its
90
+ // Append-only and idempotent: an existing `AGENTS.md` is a file someone wrote, so humanish adds its
90
91
  // own section once and never rewrites theirs.
91
92
  async function planAgentsFile(preparedProjectRoot, cwd, plan) {
92
93
  const agentsPath = "AGENTS.md";
@@ -136,10 +137,22 @@ async function planStarterFiles(preparedProjectRoot, cwd, files, localBrowserReq
136
137
  const existing = await readTextIfExists(preparedProjectRoot, file.path);
137
138
  if (existing !== null &&
138
139
  localBrowserRequested &&
139
- file.path === "humanish/labs/local-browser.yaml") {
140
- plan.warnings.push("Skipped --local-browser/--local-mission: humanish/labs/local-browser.yaml already exists and init never overwrites it.");
140
+ file.path === "humanish/studies/local-browser.yaml") {
141
+ plan.warnings.push("Skipped --local-browser/--local-mission: humanish/studies/local-browser.yaml already exists and init never overwrites it.");
141
142
  }
142
- if (existing === null) {
143
+ const others = existing === null ? await otherStudyFilesFor(preparedProjectRoot, file.path) : [];
144
+ if (others.length > 0) {
145
+ const stem = studyFileStem(path.basename(file.path));
146
+ plan.changes.push({
147
+ path: file.path,
148
+ action: "skip",
149
+ target: file.plane,
150
+ reason: `${others.join(", ")} already uses the name ${stem}`,
151
+ });
152
+ const legacy = others.some((other) => other.split(path.sep).includes("labs"));
153
+ plan.warnings.push(`Skipped ${file.path}: ${others.join(", ")} already uses the name ${stem}, and a second file with that name would make \`run ${stem}\` fail.${legacy ? " Run humanish migrate to move it to a studies/ directory." : ""}`);
154
+ }
155
+ else if (existing === null) {
143
156
  plan.changes.push({
144
157
  path: file.path,
145
158
  action: "create",
@@ -172,6 +185,25 @@ async function planStarterFiles(preparedProjectRoot, cwd, files, localBrowserReq
172
185
  }
173
186
  }
174
187
  }
188
+ /**
189
+ * The study files that already use a starter study's name in any study directory, other than the
190
+ * starter's own path. An unsafe path counts as present, so init skips the starter rather than
191
+ * failing.
192
+ */
193
+ async function otherStudyFilesFor(preparedProjectRoot, relativePath) {
194
+ const stem = studyFileStem(path.basename(relativePath));
195
+ const inStudyDirectory = STUDY_DIRECTORIES.some((directory) => directory.relativeDir === path.dirname(relativePath));
196
+ if (stem === undefined || !inStudyDirectory)
197
+ return [];
198
+ return otherStudyFiles(stem, async (candidate) => {
199
+ try {
200
+ return (await readTextIfExists(preparedProjectRoot, candidate)) !== null;
201
+ }
202
+ catch {
203
+ return true;
204
+ }
205
+ }, relativePath);
206
+ }
175
207
  /** Create each ignored runtime directory that is missing. */
176
208
  async function planRuntimeDirectories(preparedProjectRoot, cwd, plan) {
177
209
  for (const directory of runtimeDirectories) {
@@ -254,7 +286,7 @@ async function firstRunEnvironment(env, cwd) {
254
286
  const present = (name) => keys.some((key) => key.name === name && key.source !== null);
255
287
  let hasDesktopSdk = false;
256
288
  try {
257
- // Resolution from the PROJECT, not from wherever humanish itself lives.
289
+ // Resolution starts from the project, wherever humanish itself is installed.
258
290
  const { createRequire } = await import("node:module");
259
291
  createRequire(path.join(process.cwd(), "package.json")).resolve("@e2b/desktop");
260
292
  hasDesktopSdk = true;
@@ -1,2 +1,4 @@
1
1
  /** The first key in `raw` that LAB_KEYS does not list, as an error message; undefined if none. */
2
2
  export declare function findUnknownLabKey(raw: unknown): string | undefined;
3
+ /** The first key in a humanish.study.v3 document that the format does not have; undefined if none. */
4
+ export declare function findUnknownStudyKey(raw: unknown): string | undefined;