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
@@ -1,9 +1,9 @@
1
- // `humanish export`: one file a coworker can open (#471).
1
+ // `humanish export`: one file a coworker can open.
2
2
  //
3
3
  // A run is a directory. Sharing it meant a tunnel (`serve --expose`) or a hand-zipped bundle,
4
4
  // neither of which is "send one thing". The Observer is already a single-file artifact with the
5
5
  // run's data inlined; what keeps it from travelling is the screenshots it references by path.
6
- // Export embeds each unique raster once and writes ONE .html that opens offline.
6
+ // Export embeds each unique raster once and writes one .html that opens offline.
7
7
  //
8
8
  // Share safety is the point, not a step: export runs verify inside the flow and refuses a bundle
9
9
  // that is not share_ready. A local_only bundle (raw screenshots) exports only with an explicit
@@ -18,10 +18,10 @@ import { resolveRunPath } from "../run/locate.js";
18
18
  import { verifyRun } from "../verify/verify.js";
19
19
  import {} from "../run/bundle.js";
20
20
  import { exportRedactedBundle } from "./export-bundle.js";
21
- import { loadStudyAnalysis } from "../analysis/load.js";
22
- import { studyAnalysisSharingProblems } from "../analysis/sharing.js";
21
+ import { loadAnalysis } from "../analysis/load.js";
22
+ import { analysisSharingProblems } from "../analysis/sharing.js";
23
23
  import { EVIDENCE_LIMITS, validateAnalysisEvidence } from "../analysis/evidence.js";
24
- import { readBoundedStudyFile } from "../run/study-files.js";
24
+ import { readBoundedFile } from "../run/evidence-files.js";
25
25
  import { shellQuote } from "../substrates/shell.js";
26
26
  const EXPORT_SCHEMA = "humanish.export-result.v1";
27
27
  /** Past this the file stops being a thing you attach to an email. Declared, never silent. */
@@ -40,7 +40,7 @@ const IMAGE_MIME = {
40
40
  export function localOnlyBanner(reasons) {
41
41
  const why = reasons.length === 0 ? "" : ` (${reasons.join(", ")})`;
42
42
  return (`<div id="humanish-local-only" role="alert" tabindex="0" style="position:sticky;top:0;z-index:2147483647;max-height:40vh;overflow:auto;background:#7a1f1f;color:#fff;font:600 14px/1.4 system-ui,sans-serif;padding:10px 16px;text-align:center">` +
43
- `LOCAL ONLY. This export was made from a bundle that is not share-safe${why}. Do not forward it outside the team that owns the run.` +
43
+ `Local only. This export was made from a bundle that is not share-safe${why}. Do not forward it outside the team that owns the run.` +
44
44
  `</div>`);
45
45
  }
46
46
  async function isInside(root, candidate) {
@@ -73,7 +73,7 @@ export async function exportRun(cwdInput, runInput, options = {}, deps = {}) {
73
73
  return slot;
74
74
  // Every string in the data that names an image file inside the run becomes an asset reference. Paths are
75
75
  // run-root-relative in the data; a path that resolves outside the run is left alone, never read.
76
- const analysis = await loadStudyAnalysis(runPaths);
76
+ const analysis = await loadAnalysis(runPaths);
77
77
  const data = await currentObserverData(runPaths, analysis, slot);
78
78
  if (data === undefined)
79
79
  return exportFailure(cwd, runInput, "HUMANISH_EXPORT_VERIFY_FAILED", "Source evidence changed while preparing the analysis export.");
@@ -146,9 +146,8 @@ async function readObserverSlot(cwd, runInput, runRoot, runId, verified, deps, w
146
146
  html = await readFile(observerPath, "utf8");
147
147
  }
148
148
  catch {
149
- // `run` writes observer-data.json and no index.html; `watch` writes both (#597). The
150
- // 0.72.0 dogfood participant hit this on its first export. Render it here, from the same
151
- // artifact watch uses, so what produced the run never decides whether it can be sent.
149
+ // `run` writes observer-data.json and no index.html; `watch` writes both. Render it here, from
150
+ // the same artifact watch uses, so what produced the run never decides whether it can be sent.
152
151
  const rendered = await (deps.render ?? ((c, r) => renderObserver(c, r, { open: false })))(cwd, runInput).catch(() => ({ ok: false }));
153
152
  try {
154
153
  if (!rendered.ok)
@@ -175,7 +174,7 @@ async function currentObserverData(runPaths, analysis, slot) {
175
174
  const saved = JSON.parse(slot);
176
175
  if (analysis.state !== "ready" || !analysis.analysis)
177
176
  return { value: saved };
178
- const source = await readBoundedStudyFile(runPaths, "run.json", EVIDENCE_LIMITS.sourceBytes);
177
+ const source = await readBoundedFile(runPaths, "run.json", EVIDENCE_LIMITS.sourceBytes);
179
178
  if (!source ||
180
179
  createHash("sha256").update(source).digest("hex") !== analysis.analysis.sourceRunSha256)
181
180
  return undefined;
@@ -211,7 +210,7 @@ async function inlineImages(runPaths, runRoot, data, analysis, options, warnings
211
210
  for (const candidate of candidates) {
212
211
  if (!(await isInside(runRoot, candidate)))
213
212
  continue;
214
- const bytes = await readBoundedStudyFile(runPaths, path.relative(runRoot, candidate), options.maxBytes ?? DEFAULT_EXPORT_MAX_BYTES);
213
+ const bytes = await readBoundedFile(runPaths, path.relative(runRoot, candidate), options.maxBytes ?? DEFAULT_EXPORT_MAX_BYTES);
215
214
  if (bytes === null)
216
215
  continue;
217
216
  if (bytes.byteLength > MAX_PORTABLE_IMAGE_BYTES) {
@@ -281,7 +280,7 @@ function makePortable(inlined, verified) {
281
280
  }
282
281
  }
283
282
  }
284
- // What verify said, in the file, so the chrome can agree with the result envelope (#584).
283
+ // What verify said, in the file, so the chrome can agree with the result envelope.
285
284
  const publicSafety = (inlined.publicSafety ?? {});
286
285
  inlined.publicSafety = {
287
286
  ...publicSafety,
@@ -302,7 +301,7 @@ async function recheckAnalysis(runPaths, analysis, verified, inlined, options) {
302
301
  // Revalidate the independent interpretation against source evidence. Never trust a
303
302
  // saved HTML slot or traverse model-provided strings as image paths.
304
303
  if (analysis.state === "ready" && analysis.analysis) {
305
- const source = await readBoundedStudyFile(runPaths, "run.json", EVIDENCE_LIMITS.sourceBytes);
304
+ const source = await readBoundedFile(runPaths, "run.json", EVIDENCE_LIMITS.sourceBytes);
306
305
  try {
307
306
  if (!source)
308
307
  throw new Error("source unavailable");
@@ -312,7 +311,7 @@ async function recheckAnalysis(runPaths, analysis, verified, inlined, options) {
312
311
  return "changed";
313
312
  }
314
313
  }
315
- const analysisSharing = studyAnalysisSharingProblems(analysis);
314
+ const analysisSharing = analysisSharingProblems(analysis);
316
315
  if (!analysisSharing.sensitive && !analysisSharing.unverified)
317
316
  return "ok";
318
317
  verified.shareSafety = {
@@ -358,7 +357,7 @@ function renderExportHtml(inlined, analysis, assets, verified, watermarked, omit
358
357
  }
359
358
  export function formatExportHuman(result) {
360
359
  if (!result.ok)
361
- return `${result.error.code}: ${result.error.message}\n`;
360
+ return { error: result.error };
362
361
  if (result.format === "bundle") {
363
362
  return [
364
363
  `humanish export ${result.runId}`,
@@ -373,7 +372,7 @@ export function formatExportHuman(result) {
373
372
  const lines = [
374
373
  `humanish export ${result.runId}`,
375
374
  `file: ${result.path} (${(result.bytes / 1024).toFixed(0)} KB, ${result.embeddedImages} image(s) embedded)`,
376
- `share safety: ${result.shareSafety.status}${result.watermarked ? " — WATERMARKED LOCAL ONLY" : ""}`,
375
+ `share safety: ${result.shareSafety.status}${result.watermarked ? " (watermarked: local only)" : ""}`,
377
376
  ...result.warnings.map((warning) => `warning: ${warning}`),
378
377
  ];
379
378
  return `${lines.join("\n")}\n`;
@@ -12,12 +12,12 @@ export interface FeedbackResult {
12
12
  issueMarkdown?: string;
13
13
  issueUrl?: string;
14
14
  draft?: FeedbackDraft;
15
- /** Every usable candidate on the bundle, so a multi-lane study's second and third findings can be
16
- * chosen with `--candidate` instead of being invisible behind the first (#609). */
15
+ /** Every usable candidate on the bundle, so a multi-participant study's second and third findings can be
16
+ * chosen with `--candidate` instead of being invisible behind the first. */
17
17
  candidates?: FeedbackCandidateSummary[];
18
18
  shareSafety?: VerifyResult["shareSafety"];
19
19
  error?: {
20
- code: "HUMANISH_RUN_NOT_FOUND" | "HUMANISH_INVALID_RUN_BUNDLE" | "HUMANISH_INVALID_FEEDBACK_DRAFT" | "HUMANISH_FEEDBACK_SHARE_SAFETY_BLOCKED" | "HUMANISH_FEEDBACK_CANDIDATE_NOT_FOUND";
20
+ code: "HUMANISH_RUN_NOT_FOUND" | "HUMANISH_INVALID_RUN_BUNDLE" | "HUMANISH_INVALID_FEEDBACK_DRAFT" | "HUMANISH_FEEDBACK_SHARE_SAFETY_BLOCKED" | "HUMANISH_FEEDBACK_CANDIDATE_NOT_FOUND" | "HUMANISH_FEEDBACK_REQUIRES_LIVE_RUN";
21
21
  message: string;
22
22
  };
23
23
  }
@@ -1,6 +1,7 @@
1
1
  // The feedback commands: resolve a run, draft a feedback issue from it, verify the draft, render it
2
2
  // as an issue body or URL, and list a run's candidates. What a draft contains is in draft.ts.
3
3
  import { realpath } from "node:fs/promises";
4
+ import { runNotFoundMessage } from "../run/run-not-found.js";
4
5
  import path from "node:path";
5
6
  import { bindExistingRunArtifactPaths, isSafeRunIdSegment, resolveLatestRunDirectory, validatePreparedRunArtifactPaths, } from "../run/paths.js";
6
7
  import { bindExistingManagedHumanishOutputDirectory, readContainedRegularFile, writeContainedOutputFile, } from "../run/contained-output.js";
@@ -34,7 +35,24 @@ async function draftFeedbackBound(cwdInput, runInput, options = {}) {
34
35
  run: runInput,
35
36
  error: {
36
37
  code: "HUMANISH_RUN_NOT_FOUND",
37
- message: `Run not found: ${runInput}`,
38
+ message: await runNotFoundMessage(cwd, runInput),
39
+ },
40
+ },
41
+ };
42
+ }
43
+ // A dry run exercised no product, so it has nothing to report upstream; analyze refuses it the
44
+ // same way (ANALYSIS_REQUIRES_LIVE_RUN).
45
+ if (context.loaded.bundle.mode !== "live") {
46
+ return {
47
+ context,
48
+ result: {
49
+ schema: FEEDBACK_RESULT_SCHEMA,
50
+ ok: false,
51
+ cwd,
52
+ run: runInput,
53
+ error: {
54
+ code: "HUMANISH_FEEDBACK_REQUIRES_LIVE_RUN",
55
+ message: `Run ${context.storedRunId} is a dry run, which tests no product behavior. Feedback drafts need a live run.`,
38
56
  },
39
57
  },
40
58
  };
@@ -204,7 +222,7 @@ export async function listFeedback(cwdInput, runInput) {
204
222
  run: runInput,
205
223
  error: {
206
224
  code: "HUMANISH_RUN_NOT_FOUND",
207
- message: `Run not found: ${runInput}`,
225
+ message: await runNotFoundMessage(cwd, runInput),
208
226
  },
209
227
  };
210
228
  }
@@ -218,7 +236,7 @@ export async function listFeedback(cwdInput, runInput) {
218
236
  run: runInput,
219
237
  ...(draft ? { draftPath, draft } : {}),
220
238
  // The choice set for `draft --candidate`: a three-participant study has up to three findings,
221
- // and until #609 only the first ever reached a draft.
239
+ // and each can reach a draft.
222
240
  candidates: summarizeCandidates(context.loaded.bundle),
223
241
  };
224
242
  }
@@ -220,7 +220,7 @@ async function probeElement(op, session, contextId, expression) {
220
220
  /**
221
221
  * Preparation: the owner check, a CDP session (recorded on the handle as soon as it exists, so
222
222
  * disposal detaches a partial acquisition), the owned top frame, an isolated world, and the
223
- * PREPARE probe.
223
+ * `PREPARE` probe.
224
224
  */
225
225
  async function acquireIsolatedWorld(settings, state, detach, prepared, op) {
226
226
  await assertOwnerReady(settings, op);
@@ -267,7 +267,7 @@ function disposePrepared(state, detach, prepared, self) {
267
267
  return prepared.disposal;
268
268
  }
269
269
  /**
270
- * The handle for one preparation. paste inserts the text once: owner check, RECHECK probe, owner
270
+ * The handle for one preparation. paste inserts the text once: owner check, `RECHECK` probe, owner
271
271
  * check, check, then insertText. close is the handle's disposal.
272
272
  */
273
273
  function preparedHandle(settings, state, prepared, dispose) {
@@ -9,6 +9,6 @@ export declare function createGuestDesktopNativeTools(options: {
9
9
  display: string;
10
10
  /** An owner-created private directory inside the disposable guest. */
11
11
  temporaryDirectory: string;
12
- /** Owner-created cookie file; never inherit an operator's XAUTHORITY. */
12
+ /** Owner-created cookie file; never inherit an operator's `XAUTHORITY`. */
13
13
  xauthority: string;
14
14
  }): GuestDesktopNativeTools;
@@ -105,7 +105,7 @@ export async function runGuestRuntime(options) {
105
105
  isAuthorized: () => !authority.aborted,
106
106
  ...(desktop.finishRecording ? { finishRecording: desktop.finishRecording } : {}),
107
107
  });
108
- // No await in this handoff: an immediate HELLO already has its sole receiver.
108
+ // No await in this handoff: an immediate hello already has its sole receiver.
109
109
  options.transport.write(encodeGuestBootstrap(identity, true), (error) => {
110
110
  if (error)
111
111
  terminal();
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- export { runLab } from "./run-lab.js";
2
- export type { LabOutcome, LabResult, RunLabOptions } from "./run-lab.js";
3
- export type { LabEvent } from "./lab/run-lab-events.js";
4
- export type { ProviderContext } from "./lab/run-lab-options.js";
1
+ export { runPackageLab as runStudy } from "./run-lab.js";
2
+ export type { LabOutcome as StudyOutcome, LabResult as StudyResult, RunLabOptions as RunStudyOptions, } from "./run-lab.js";
3
+ export type { LabEvent as StudyEvent } from "./lab/run-lab-events.js";
4
+ export type { ProviderContext } from "./lab/run-lab-homes.js";
5
5
  export { routeOf } from "./lab/plan.js";
6
- export type { LabRoute } from "./lab/plan.js";
7
- export { parseLabConfig } from "./lab/config.js";
8
- export { LAB_CONFIG_SCHEMA } from "./lab/types.js";
9
- export type { LabConfig } from "./lab/types.js";
6
+ export type { LabRoute as StudyRoute } from "./lab/plan.js";
7
+ export { parseLabConfig as parseStudy } from "./lab/config.js";
8
+ export { STUDY_SCHEMA } from "./lab/types.js";
9
+ export type { LabConfig as StudyConfig } from "./lab/types.js";
10
10
  export { verifyRun } from "./verify/verify.js";
11
11
  export type { VerifyResult } from "./verify/verify.js";
12
12
  export { renderObserver } from "./observer/render.js";
@@ -14,19 +14,18 @@ export type { ObserverResult } from "./observer/render.js";
14
14
  export type { RunBundle, RunFeedbackCandidate } from "./run/bundle.js";
15
15
  export type { ActorTrace } from "./actors/contract.js";
16
16
  export { runComputerUseLoop, stableProgressKey } from "./actors/computer-use/loop.js";
17
- export type { CuaAction, CuaExecutor, CuaLoopOptions, CuaLoopResult, CuaObservation, CuaProvider, CuaSafetyCheck, CuaTurn, CuaTurnRequest, } from "./actors/computer-use/loop.js";
17
+ export type { CuaAction as ComputerUseAction, CuaExecutor as ComputerUseExecutor, CuaLoopOptions as ComputerUseLoopOptions, CuaLoopResult as ComputerUseLoopResult, CuaObservation as ComputerUseObservation, CuaProvider as ComputerUseProvider, CuaSafetyCheck as ComputerUseSafetyCheck, CuaTurn as ComputerUseTurn, CuaTurnRequest as ComputerUseTurnRequest, } from "./actors/computer-use/loop.js";
18
18
  export type { ActorCapabilities } from "./actors/contract.js";
19
19
  export { createOpenAiResponsesProvider } from "./actors/computer-use/openai-provider.js";
20
20
  export type { OpenAiResponsesProviderOptions } from "./actors/computer-use/openai-provider.js";
21
- export { CuaAdmissionLimitError } from "./actors/computer-use/admission-limit.js";
21
+ export { CuaAdmissionLimitError as ComputerUseAdmissionLimitError } from "./actors/computer-use/admission-limit.js";
22
22
  export { defaultRedactionHooks } from "./evidence/redaction.js";
23
23
  export type { RedactionHooks } from "./evidence/redaction.js";
24
24
  export type { E2BDesktopSandbox } from "./substrates/e2b/sdk.js";
25
+ export { browserScorer, terminalScorer } from "./lab/adapter-scorer-loader.js";
25
26
  export type { AdapterScorerModule, AdapterScoringContext } from "./lab/adapter-scorer-loader.js";
26
- export type { BrowserLabScoringContext } from "./lab/adapter-extension.js";
27
+ export type { BrowserLabScoringContext as BrowserScoringContext } from "./lab/adapter-extension.js";
27
28
  export type { TerminalProductScoringContext } from "./routes/terminal/types.js";
28
29
  export type { RunAdapterArtifact, RunAdapterScore } from "./run/bundle.js";
29
- export { routesToComputerUse, routesToConcurrentSharedWorld, routesToExternalPublicSharedWorld, routesToProvisionedSharedWorld, routesToScriptedBrowser, routesToSharedWorld, routesToTerminalProduct, } from "./lab/routing.js";
30
- export { selectLabBackend } from "./lab/plan.js";
31
- export { actorResolvesToTerminal, concurrentSharedWorldValidationReason, cuaLaneCount, cuaLaneValidationReason, externalPublicSharedWorldValidationReason, MAX_CUA_LANES, resolveLabDryRun, resolveSeatUrl, runConcurrentSharedWorld, runCuaActorLab, runCuaActorSession, runDryRun, runScriptedBrowserLab, runTerminalProductLab, sharedWorldValidationReason, } from "./deprecated.js";
32
- export type { AutomaticAnalysisHooks, BrowserLabAdapterHooks, ConcurrentSharedWorldLabResult, CuaActorLabHooks, CuaActorLabResult, LabBackend, RunConcurrentSharedWorldLabOptions, RunCuaActorLabOptions, RunOptions, RunResult, RunScriptedBrowserLabOptions, RunTerminalProductLabOptions, ScriptedBrowserLabHooks, ScriptedBrowserLabResult, SharedWorldLabHooks, SubjectPhaseEvent, TerminalProductLabHooks, TerminalProductLabResult, } from "./deprecated.js";
30
+ export { CuaAdmissionLimitError, LAB_CONFIG_SCHEMA, parseLabConfig, runLab, } from "./library-aliases.js";
31
+ export type { BrowserLabScoringContext, CuaAction, CuaExecutor, CuaLoopOptions, CuaLoopResult, CuaObservation, CuaProvider, CuaSafetyCheck, CuaTurn, CuaTurnRequest, LabConfig, LabEvent, LabOutcome, LabResult, LabRoute, RunLabOptions, } from "./library-aliases.js";
package/dist/index.js CHANGED
@@ -1,21 +1,20 @@
1
- // The library surface: what an adopter needs to run a lab, read a run, bring a participant or
1
+ // The library surface: what an adopter needs to run a study, read a run, bring a participant or
2
2
  // score a run. Everything else is internal and reached through the `humanish` bin. See
3
3
  // docs/contracts/schemas.md, "Library options", and the site's library page.
4
- // Run a lab.
5
- export { runLab } from "./run-lab.js";
4
+ // Run a study.
5
+ export { runPackageLab as runStudy } from "./run-lab.js";
6
6
  export { routeOf } from "./lab/plan.js";
7
- export { parseLabConfig } from "./lab/config.js";
8
- export { LAB_CONFIG_SCHEMA } from "./lab/types.js";
7
+ export { parseLabConfig as parseStudy } from "./lab/config.js";
8
+ export { STUDY_SCHEMA } from "./lab/types.js";
9
9
  // Read a run.
10
10
  export { verifyRun } from "./verify/verify.js";
11
11
  export { renderObserver } from "./observer/render.js";
12
12
  // Bring a participant.
13
13
  export { runComputerUseLoop, stableProgressKey } from "./actors/computer-use/loop.js";
14
14
  export { createOpenAiResponsesProvider } from "./actors/computer-use/openai-provider.js";
15
- export { CuaAdmissionLimitError } from "./actors/computer-use/admission-limit.js";
15
+ export { CuaAdmissionLimitError as ComputerUseAdmissionLimitError } from "./actors/computer-use/admission-limit.js";
16
16
  export { defaultRedactionHooks } from "./evidence/redaction.js";
17
- // Routing: the planLab series deprecates these and removes them in the next minor.
18
- export { routesToComputerUse, routesToConcurrentSharedWorld, routesToExternalPublicSharedWorld, routesToProvisionedSharedWorld, routesToScriptedBrowser, routesToSharedWorld, routesToTerminalProduct, } from "./lab/routing.js";
19
- export { selectLabBackend } from "./lab/plan.js";
20
- // Deprecated this minor, removed in the next.
21
- export { actorResolvesToTerminal, concurrentSharedWorldValidationReason, cuaLaneCount, cuaLaneValidationReason, externalPublicSharedWorldValidationReason, MAX_CUA_LANES, resolveLabDryRun, resolveSeatUrl, runConcurrentSharedWorld, runCuaActorLab, runCuaActorSession, runDryRun, runScriptedBrowserLab, runTerminalProductLab, sharedWorldValidationReason, } from "./deprecated.js";
17
+ // Score a run.
18
+ export { browserScorer, terminalScorer } from "./lab/adapter-scorer-loader.js";
19
+ // The 0.107 names, deprecated until 0.109 removes them. Each is its new name's value or type.
20
+ export { CuaAdmissionLimitError, LAB_CONFIG_SCHEMA, parseLabConfig, runLab, } from "./library-aliases.js";
@@ -1,6 +1,6 @@
1
1
  export interface ResolvedKeyFill {
2
2
  name: string;
3
- /** Human-readable source label (a path or command name) — never a value. */
3
+ /** Human-readable source label (a path or command name), never a value. */
4
4
  source: string;
5
5
  }
6
6
  export interface KeyResolutionDeps {
@@ -13,12 +13,14 @@ export declare function userKeyStorePath(env: NodeJS.ProcessEnv, deps?: KeyResol
13
13
  /**
14
14
  * Fill missing provider keys into `env` from the discovery chain, announcing each fill as
15
15
  * `NAME from SOURCE`. Returns the fills. Opt-out: HUMANISH_STRICT_KEYS=1 returns [] untouched.
16
+ * With `announced`, every key is still filled, and only the fills it names are announced.
16
17
  */
17
18
  export declare function discoverProviderKeys(args: {
18
19
  cwd: string;
19
20
  env: NodeJS.ProcessEnv;
20
21
  announce: (line: string) => void;
21
22
  deps?: KeyResolutionDeps;
23
+ announced?: ReadonlySet<string>;
22
24
  }): Promise<ResolvedKeyFill[]>;
23
25
  export interface KeySourceProbe {
24
26
  name: string;
@@ -27,8 +29,8 @@ export interface KeySourceProbe {
27
29
  /** The command/path that would fill it when missing. */
28
30
  hint: string;
29
31
  }
30
- /** The nearest fill instruction for a missing key — used by doctor rows and appended to
31
- * *_KEYS_MISSING errors so the failure names the fix, not just the absence (#436). */
32
+ /** The nearest fill instruction for a missing key. Doctor rows use it, and it is appended to
33
+ * *_KEYS_MISSING errors so the failure names the fix. */
32
34
  export declare function missingKeyHint(name: string): string;
33
35
  /** One shared suffix for *_KEYS_MISSING messages: where discovery looked, and what fills each
34
36
  * missing key. Pure text; never values. */
@@ -45,10 +47,10 @@ export declare function probeKeySources(names: readonly string[], args: {
45
47
  /** Resolve a `humanish keys set` target: a vendor alias or a raw env name. Null = invalid. */
46
48
  export declare function resolveKeyName(vendorOrName: string): string | null;
47
49
  /** Write one key into the user store (0700 dir, 0600 file). Only allowlisted provider names
48
- * are storable (the store feeds implicit discovery — an arbitrary-name store would be an env
50
+ * are storable (the store feeds implicit discovery, so an arbitrary-name store would be an env
49
51
  * injection vector with extra steps). The value must be a single non-empty line that
50
52
  * round-trips the store's own parser byte-identically, and the write refuses symlinks at the
51
- * file AND its parent directory (red-team findings). */
53
+ * file and its parent directory. */
52
54
  export declare function setUserKey(name: string, value: string, env: NodeJS.ProcessEnv, deps?: KeyResolutionDeps): {
53
55
  path: string;
54
56
  };
@@ -1,30 +1,30 @@
1
- // Provider-key discovery (#436): resolve the keys a live run needs through each vendor's
1
+ // Provider-key discovery: resolve the keys a live run needs through each vendor's
2
2
  // native chain instead of demanding a per-repo --env-file that operators hand-copy keys into.
3
3
  //
4
- // The chain, per key, FILL-ONLY (a rung never overrides anything already present):
5
- // 1. process env — including whatever --env-file just loaded (explicit always wins);
6
- // 2. `.humanish/local/provider.env` — the project-local overlay this CLI's own --help
4
+ // The chain, per key, fill-only (a rung never overrides anything already present):
5
+ // 1. process env, including whatever --env-file just loaded (explicit always wins);
6
+ // 2. `.humanish/local/provider.env`, the project-local overlay this CLI's own --help
7
7
  // examples document;
8
- // 3. the OWNING vendor's native store, where one exists:
8
+ // 3. the owning vendor's native store, where one exists:
9
9
  // E2B_API_KEY <- ~/.e2b/config.json (written by `e2b auth login`);
10
10
  // GH_TOKEN <- `gh auth token` (the gh CLI's credential chain);
11
11
  // 4. the humanish user-level store `$XDG_CONFIG_HOME/humanish/keys.env`, written only by
12
- // `humanish keys set` (0600, prompted or --stdin) — the fallback for vendors that ship
12
+ // `humanish keys set` (0600, prompted or --stdin), the fallback for vendors that ship
13
13
  // no machine chain of their own (OpenAI, Anthropic).
14
14
  //
15
- // Every fill is ANNOUNCED by key name + source, never by value. The subject app's own
16
- // `.env`/`.env.local` are NEVER read — those hold product credentials, a different class
17
- // (#11); this module only reads humanish-owned files and vendor-owned stores.
18
- // `HUMANISH_STRICT_KEYS=1` disables every rung below process env (the pre-#436 behavior).
15
+ // Every fill is announced by key name + source, never by value. The subject app's own
16
+ // `.env`/`.env.local` are never read: those hold product credentials, a different class
17
+ // of secret; this module only reads humanish-owned files and vendor-owned stores.
18
+ // `HUMANISH_STRICT_KEYS=1` disables every rung below process env.
19
19
  import { spawn } from "node:child_process";
20
20
  import { chmodSync, closeSync, constants as fsConstants, existsSync, ftruncateSync, lstatSync, mkdirSync, openSync, readFileSync, writeSync, } from "node:fs";
21
21
  import { homedir } from "node:os";
22
22
  import path from "node:path";
23
23
  import { loadEnvFile } from "./env-file.js";
24
- /** The ONLY names implicit discovery may fill (and `humanish keys set` may store). Everything
24
+ /** The only names implicit discovery may fill (and `humanish keys set` may store). Everything
25
25
  * else in an overlay/store file is ignored-and-named: a repo-planted NODE_OPTIONS/LD_PRELOAD
26
26
  * must never enter process env off a file the operator did not explicitly pass (an explicit
27
- * --env-file remains the operator's own full-file load). Red-team finding, #436. */
27
+ * --env-file remains the operator's own full-file load). */
28
28
  const KNOWN_PROVIDER_KEYS = [
29
29
  "OPENAI_API_KEY",
30
30
  "ANTHROPIC_API_KEY",
@@ -51,8 +51,8 @@ const PROJECT_OVERLAY_RELATIVE = path.join(".humanish", "local", "provider.env")
51
51
  export function userKeyStorePath(env, deps = {}) {
52
52
  const home = deps.homeDir ?? homedir();
53
53
  const declared = env.XDG_CONFIG_HOME?.trim();
54
- // The XDG spec: a relative XDG_CONFIG_HOME MUST be ignored. Honoring one would make the
55
- // key store cwd-relative — `humanish keys set` would write a secret into the current repo.
54
+ // The XDG spec: a relative XDG_CONFIG_HOME must be ignored. Honoring one would make the
55
+ // key store cwd-relative: `humanish keys set` would write a secret into the current repo.
56
56
  const configHome = declared !== undefined && declared !== "" && path.isAbsolute(declared)
57
57
  ? declared
58
58
  : path.join(home, ".config");
@@ -61,7 +61,7 @@ export function userKeyStorePath(env, deps = {}) {
61
61
  function e2bConfigPath(deps) {
62
62
  return path.join(deps.homeDir ?? homedir(), ".e2b", "config.json");
63
63
  }
64
- /** Default exec: bounded, quiet, stdin closed; null on ANY failure. Never throws. */
64
+ /** Default exec: bounded, quiet, stdin closed; null on any failure. Never throws. */
65
65
  function defaultExecText(command, args, timeoutMs, env) {
66
66
  return new Promise((resolve) => {
67
67
  let child;
@@ -128,7 +128,7 @@ function readE2bConfigKey(deps) {
128
128
  return null;
129
129
  }
130
130
  }
131
- /** Refuse to READ a store through a symlink: a repo-local overlay that is secretly a link to
131
+ /** Refuse to read a store through a symlink: a repo-local overlay that is secretly a link to
132
132
  * an unrelated file is exactly the retargeting shape the artifact paths refuse elsewhere. */
133
133
  function isRegularFile(filePath) {
134
134
  try {
@@ -141,25 +141,26 @@ function isRegularFile(filePath) {
141
141
  /**
142
142
  * Fill missing provider keys into `env` from the discovery chain, announcing each fill as
143
143
  * `NAME from SOURCE`. Returns the fills. Opt-out: HUMANISH_STRICT_KEYS=1 returns [] untouched.
144
+ * With `announced`, every key is still filled, and only the fills it names are announced.
144
145
  */
145
146
  export async function discoverProviderKeys(args) {
146
- const { cwd, env, announce } = args;
147
+ const { cwd, env, announce, announced } = args;
147
148
  const deps = args.deps ?? {};
148
149
  if (env.HUMANISH_STRICT_KEYS?.trim() === "1")
149
150
  return [];
150
151
  const fills = [];
151
152
  const ignored = [];
152
- // Fill-only means PRESENCE wins, including an explicitly-set empty value: an operator who
153
- // exported OPENAI_API_KEY="" said "off", and a rung that "fixes" that has overridden them
154
- // (red-team finding). Only a truly-unset name is fillable.
153
+ // Fill-only means presence wins, including an explicitly-set empty value: an operator who
154
+ // exported OPENAI_API_KEY="" said "off", and a rung that "fixes" that has overridden them.
155
+ // Only a truly-unset name is fillable.
155
156
  const fillable = (name) => env[name] === undefined;
156
157
  const fill = (name, value, source) => {
157
158
  env[name] = value;
158
159
  fills.push({ name, source });
159
160
  };
160
- // Rung 2: the documented project-local overlay. Parsed ATOMICALLY against a scratch env so a
161
- // file loadEnvFile rejects can never half-apply (red-team finding: earlier lines used to land
162
- // in env unannounced before the parse error aborted). Only allowlisted provider names cross
161
+ // Rung 2: the documented project-local overlay. Parsed atomically against a scratch env so a
162
+ // file loadEnvFile rejects can never half-apply: otherwise lines before the parse error would
163
+ // land in env unannounced. Only allowlisted provider names cross
163
164
  // from the file into the real env.
164
165
  const overlayPath = path.resolve(cwd, PROJECT_OVERLAY_RELATIVE);
165
166
  if (isRegularFile(overlayPath) && !dirIsSymlink(overlayPath)) {
@@ -184,7 +185,7 @@ export async function discoverProviderKeys(args) {
184
185
  if (teamKey !== null)
185
186
  fill("E2B_API_KEY", teamKey, "~/.e2b/config.json (e2b auth login)");
186
187
  }
187
- // Rung 3b: the gh CLI's credential chain. Only consulted when NEITHER GitHub env name is
188
+ // Rung 3b: the gh CLI's credential chain. Only consulted when neither GitHub env name is
188
189
  // present; fills GH_TOKEN (the name humanish reads first). gh runs without any provider key in
189
190
  // its environment, so the keys the rungs above just filled stay in this process.
190
191
  if (fillable("GH_TOKEN") && fillable("GITHUB_TOKEN")) {
@@ -193,9 +194,9 @@ export async function discoverProviderKeys(args) {
193
194
  if (token !== null)
194
195
  fill("GH_TOKEN", token, "gh auth token");
195
196
  }
196
- // Rung 4: the humanish user-level store — read with the SAME lenient parser `keys set`/`list`
197
+ // Rung 4: the humanish user-level store, read with the same lenient parser `keys set`/`list`
197
198
  // use, so one hand-mangled line degrades to that line alone instead of silently voiding the
198
- // whole store (red-team finding: the strict parser disagreed with the store's own reader).
199
+ // whole store, as the strict parser would.
199
200
  const storePath = userKeyStorePath(env, deps);
200
201
  if (isRegularFile(storePath) && !dirIsSymlink(storePath)) {
201
202
  for (const [name, value] of readStoreEntries(storePath)) {
@@ -209,13 +210,14 @@ export async function discoverProviderKeys(args) {
209
210
  }
210
211
  }
211
212
  for (const fill_ of fills)
212
- announce(`humanish keys: ${fill_.name} from ${fill_.source}`);
213
+ if (announced === undefined || announced.has(fill_.name))
214
+ announce(`humanish keys: ${fill_.name} from ${fill_.source}`);
213
215
  for (const name of ignored)
214
- announce(`humanish keys: ignored non-provider name ${name} — implicit discovery fills provider keys only; pass the file via --env-file to load everything in it`);
216
+ announce(`humanish keys: ignored ${name}, which is not a provider key. Discovery loads provider keys only; pass the file with --env-file to load every name in it.`);
215
217
  return fills;
216
218
  }
217
- /** True when the file's PARENT directory is (or traverses) a symlink at its last component —
218
- * the dir-level retarget that defeats a file-level lstat check (red-team finding). */
219
+ /** True when the file's parent directory is (or traverses) a symlink at its last component:
220
+ * the dir-level retarget that defeats a file-level lstat check. */
219
221
  function dirIsSymlink(filePath) {
220
222
  try {
221
223
  return lstatSync(path.dirname(filePath)).isSymbolicLink();
@@ -228,8 +230,8 @@ function storeLabel(env, deps) {
228
230
  const home = deps.homeDir ?? homedir();
229
231
  return userKeyStorePath(env, deps).replace(home, "~");
230
232
  }
231
- /** The nearest fill instruction for a missing key — used by doctor rows and appended to
232
- * *_KEYS_MISSING errors so the failure names the fix, not just the absence (#436). */
233
+ /** The nearest fill instruction for a missing key. Doctor rows use it, and it is appended to
234
+ * *_KEYS_MISSING errors so the failure names the fix. */
233
235
  export function missingKeyHint(name) {
234
236
  switch (name) {
235
237
  case "E2B_API_KEY":
@@ -271,7 +273,7 @@ export async function probeKeySources(names, args) {
271
273
  return names.map((name) => {
272
274
  const inEnv = args.env[name] !== undefined && args.env[name]?.trim() !== "";
273
275
  // GH_TOKEN and GITHUB_TOKEN are one credential with two spellings; a doctor row that says
274
- // "missing" while GITHUB_TOKEN sits in the env would be wrong (red-team nit).
276
+ // "missing" while GITHUB_TOKEN sits in the env would be wrong.
275
277
  const aliasInEnv = name === "GH_TOKEN" &&
276
278
  args.env.GITHUB_TOKEN !== undefined &&
277
279
  args.env.GITHUB_TOKEN.trim() !== "";
@@ -292,10 +294,10 @@ export function resolveKeyName(vendorOrName) {
292
294
  return ENV_NAME.test(vendorOrName) ? vendorOrName : null;
293
295
  }
294
296
  /** Write one key into the user store (0700 dir, 0600 file). Only allowlisted provider names
295
- * are storable (the store feeds implicit discovery — an arbitrary-name store would be an env
297
+ * are storable (the store feeds implicit discovery, so an arbitrary-name store would be an env
296
298
  * injection vector with extra steps). The value must be a single non-empty line that
297
299
  * round-trips the store's own parser byte-identically, and the write refuses symlinks at the
298
- * file AND its parent directory (red-team findings). */
300
+ * file and its parent directory. */
299
301
  export function setUserKey(name, value, env, deps = {}) {
300
302
  const trimmed = value.trim();
301
303
  if (trimmed.length === 0 || /[\u0000-\u001f\u007f]/.test(trimmed)) {
@@ -320,7 +322,7 @@ export function setUserKey(name, value, env, deps = {}) {
320
322
  entries.set(name, trimmed);
321
323
  // The written line must read back byte-identically through the store's own parser: a value
322
324
  // that parses differently (an embedded '#', a leading quote the env parser would strip)
323
- // would silently resolve to a DIFFERENT secret on the next run.
325
+ // would silently resolve to a different secret on the next run.
324
326
  const roundTrip = parseStoreLine(`${name}=${trimmed}`);
325
327
  if (roundTrip === null || roundTrip[0] !== name || roundTrip[1] !== trimmed) {
326
328
  throw new Error("The value does not round-trip the store format (avoid leading quotes and '#'); pass it via --env-file instead.");
@@ -361,8 +363,8 @@ function readStoreEntries(storePath) {
361
363
  function writeStore(storePath, entries) {
362
364
  const body = [...entries.entries()].map(([name, value]) => `${name}=${value}`).join("\n");
363
365
  const text = body.length > 0 ? `${body}\n` : "";
364
- // O_NOFOLLOW: a symlinked keys.env must never carry the write to its target (red-team
365
- // reproduced writing a secret through the link into an attacker-chosen file).
366
+ // O_NOFOLLOW: a symlinked keys.env must never carry the write to its target, which would put a
367
+ // secret into an attacker-chosen file.
366
368
  const fd = openSync(storePath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_NOFOLLOW, 0o600);
367
369
  try {
368
370
  ftruncateSync(fd, 0);