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,7 +1,9 @@
1
1
  import type { RunAdapterArtifact, RunAdapterScore, RunBundle, RunFeedbackCandidate, RunScorerProvenance } from "../run/bundle.js";
2
2
  type BrowserAdapterBackend = "cua" | "shared-world" | "concurrent-shared-world";
3
+ /** The routes that call a browser scorer. */
4
+ type BrowserScorerRoute = "computer-use" | "shared-world";
3
5
  /**
4
- * Product-agnostic scoring context for browser/computer-use lanes. Product-specific
6
+ * Product-agnostic scoring context for browser/computer-use routes. Product-specific
5
7
  * evidence/rubrics stay in the adopter's repo; core provides the assembled bundle
6
8
  * plus stable run identifiers and never learns product nouns.
7
9
  */
@@ -16,13 +18,28 @@ export interface BrowserLabScoringContext {
16
18
  labId: string;
17
19
  runId: string;
18
20
  actor: string;
21
+ /** The route that ran the participants. */
22
+ route: BrowserScorerRoute;
23
+ /**
24
+ * @deprecated Use `route`. `cua` is `computer-use` and `concurrent-shared-world` is
25
+ * `shared-world`. Reading it warns once per process; the next minor removes it.
26
+ */
19
27
  backend: BrowserAdapterBackend;
20
28
  dryRun: boolean;
29
+ /** How many participants the run had. */
30
+ participantCount: number;
31
+ /**
32
+ * @deprecated Use `participantCount`, which has the same value. Reading it warns once per
33
+ * process; the next minor removes it.
34
+ */
21
35
  laneCount: number;
22
36
  }
23
- export interface BrowserLabAdapterHooks {
37
+ /** The context a route passes to applyBrowserScorer; the deprecated fields derive from it. */
38
+ type BrowserScoringFacts = Omit<BrowserLabScoringContext, "backend" | "laneCount">;
39
+ /** The scorer functions a computer-use or shared-world run calls: `RunLabOptions.scorer`. */
40
+ export interface BrowserScorer {
24
41
  /**
25
- * Browser-route extension seam (#165): a thin adapter may score the assembled
42
+ * Browser-route extension seam: a thin adapter may score the assembled
26
43
  * browser/shared-world evidence without forking core. The score is stored as
27
44
  * namespaced `bundle.adapterScore`; product-specific component detail belongs
28
45
  * in `data`, not in core enums or review text.
@@ -47,29 +64,34 @@ export interface ScorerOutcome {
47
64
  /** Why the scorer failed the run, in order; empty when it did not. */
48
65
  failures: string[];
49
66
  }
50
- /** A DECLARED scorer that returned a malformed value never rendered a verdict. */
67
+ /** A declared scorer that returned a malformed value never rendered a verdict. */
51
68
  export declare const DECLARED_SCORER_MALFORMED = "Declared product scorer returned a malformed value instead of a verdict; a declared gate that cannot render a pass is recorded as a fail, never a silent pass.";
52
- /** A DECLARED scorer that threw never rendered a verdict. `detail` is already sanitized. */
69
+ /** A declared scorer that threw never rendered a verdict. `detail` is already sanitized. */
53
70
  export declare function declaredScorerThrew(detail: string): string;
54
- export declare function applyBrowserAdapterHooks(args: {
55
- hooks: BrowserLabAdapterHooks | undefined;
56
- context: BrowserLabScoringContext;
71
+ export declare function applyBrowserScorer(args: {
72
+ scorer: BrowserScorer | undefined;
73
+ context: BrowserScoringFacts;
57
74
  bundle: RunBundle;
58
75
  sanitize: (text: string) => string;
59
76
  warnings: string[];
60
- hookLabel: string;
61
- /** Present only when the scorer was CONFIG-DECLARED (#316); core-stamped onto the bundle as
77
+ /** Present only when the scorer was config-declared; core-stamped onto the bundle as
62
78
  * evidence of which out-of-tree module was loaded. Absent for library callers. Its presence also
63
- * makes a THROWING or MALFORMED scorer a failure — a declared gate that cannot render a pass is
79
+ * makes a throwing or malformed scorer a failure: a declared gate that cannot render a pass is
64
80
  * a fail, never a silent green. */
65
81
  scorerProvenance?: RunScorerProvenance;
66
82
  }): Promise<ScorerOutcome>;
83
+ /**
84
+ * A feedback candidate a scorer returned, accepted at the seam: the bundle's candidate shape with a
85
+ * non-empty summary. The browser and terminal seams both use it, so a candidate either seam drops
86
+ * never reaches a bundle.
87
+ */
88
+ export declare function isAdapterFeedbackCandidate(value: unknown): value is RunFeedbackCandidate;
67
89
  export declare function adapterScoreFailureMessage(bundle: RunBundle): string | undefined;
68
90
  /**
69
- * Deep-freeze a structured clone so a loaded scorer sees a READ-ONLY bundle: it cannot mutate
91
+ * Deep-freeze a structured clone so a loaded scorer sees a read-only bundle: it cannot mutate
70
92
  * noSpend/cost/review in place to launder a verdict (which would defeat the costProbe-not-loadable
71
93
  * guarantee). A tamper attempt throws in the scorer's strict-mode ESM and is caught as a hook failure.
72
- * Legitimate read-only scoring is unaffected. The seam always stamps the REAL bundle, never this view.
94
+ * Legitimate read-only scoring is unaffected. The seam always stamps the real bundle, never this view.
73
95
  */
74
96
  export declare function frozenBundleView(bundle: RunBundle): RunBundle;
75
97
  export {};
@@ -1,106 +1,128 @@
1
1
  import path from "node:path";
2
- import { isFeedbackIdempotencyKey } from "../run/feedback-shape.js";
3
- /** A DECLARED scorer that returned a malformed value never rendered a verdict. */
2
+ import { isRunAdapterScore } from "../run/bundle-shape.js";
3
+ import { withDeprecatedFields } from "./deprecated-fields.js";
4
+ import { isRunFeedbackCandidate } from "../run/feedback-shape.js";
5
+ import { isRecord } from "../run/type-guards.js";
6
+ const OLDER_BACKEND = {
7
+ "computer-use": "cua",
8
+ "shared-world": "concurrent-shared-world",
9
+ };
10
+ /** The scorer's context: the facts, plus the older `backend` and `laneCount` (deprecated-fields.ts). */
11
+ function scorerContext(facts) {
12
+ return withDeprecatedFields({ ...facts }, { name: "BrowserLabScoringContext", code: "HUMANISH_SCORING_CONTEXT_FIELD_DEPRECATED" }, {
13
+ backend: { replacement: "route", read: () => OLDER_BACKEND[facts.route] },
14
+ laneCount: { replacement: "participantCount", read: () => facts.participantCount },
15
+ });
16
+ }
17
+ /** A declared scorer that returned a malformed value never rendered a verdict. */
4
18
  export const DECLARED_SCORER_MALFORMED = "Declared product scorer returned a malformed value instead of a verdict; a declared gate that cannot render a pass is recorded as a fail, never a silent pass.";
5
- /** A DECLARED scorer that threw never rendered a verdict. `detail` is already sanitized. */
19
+ /** A declared scorer that threw never rendered a verdict. `detail` is already sanitized. */
6
20
  export function declaredScorerThrew(detail) {
7
21
  return `Declared product scorer threw before returning a verdict (${detail}); a crashed declared gate is recorded as a fail, never a silent pass.`;
8
22
  }
9
- export async function applyBrowserAdapterHooks(args) {
10
- const { hooks, context, bundle, sanitize, warnings, hookLabel, scorerProvenance } = args;
11
- if (!hooks?.score && !hooks?.deriveFeedback && !hooks?.deriveArtifacts)
23
+ export async function applyBrowserScorer(args) {
24
+ const { scorer, context, bundle, sanitize, warnings, scorerProvenance } = args;
25
+ if (!scorer?.score && !scorer?.deriveFeedback && !scorer?.deriveArtifacts)
12
26
  return { failures: [] };
13
27
  const declared = scorerProvenance !== undefined;
14
28
  // Record the loaded scorer's identity regardless of hook outcome (a throwing/invalid scorer was
15
- // still loaded and attempted). A VALID status:"fail" is a failure (library + declared, the
16
- // pre-#316 (#165) path); a DECLARED scorer that THROWS or returns MALFORMED is one too (below).
29
+ // still loaded and attempted). A valid status:"fail" is a failure (library + declared, the
30
+ // original path); a declared scorer that throws or returns a malformed value is one too (below).
17
31
  if (scorerProvenance)
18
32
  bundle.scorerProvenance = scorerProvenance;
19
- // The scorer sees a READ-ONLY view of the bundle: it cannot mutate noSpend/cost/review in place to
33
+ // The scorer sees a read-only view of the bundle: it cannot mutate noSpend/cost/review in place to
20
34
  // launder a verdict (a tamper attempt throws in the scorer's strict-mode ESM and is caught below as
21
- // a hook failure). The seam still stamps the REAL bundle.
22
- const scoringContext = {
35
+ // a hook failure). The seam still stamps the real bundle.
36
+ const scoringContext = scorerContext({
23
37
  ...context,
24
38
  bundle: frozenBundleView(context.bundle),
25
- };
39
+ });
26
40
  const scrubValue = (value) => {
27
41
  const encoded = JSON.stringify(value);
28
42
  return encoded === undefined ? value : JSON.parse(sanitize(encoded));
29
43
  };
30
44
  const failures = [];
31
- if (hooks.score) {
45
+ if (scorer?.score) {
32
46
  try {
33
- const score = await hooks.score(scoringContext);
47
+ const score = await scorer.score(scoringContext);
34
48
  const cleaned = scrubValue(score);
35
- if (isAdapterScoreShape(cleaned)) {
49
+ if (isRunAdapterScore(cleaned)) {
36
50
  bundle.adapterScore = cleaned;
37
51
  const message = adapterScoreFailureMessage(bundle);
38
52
  if (message !== undefined)
39
53
  failures.push(message);
40
54
  }
41
55
  else {
42
- warnings.push(`${hookLabel}.score returned a value that is not a well-formed humanish.adapter-score.v1 (non-empty namespace + status + numeric score + summary); dropped so the bundle stays verifiable.`);
56
+ warnings.push(`scorer.score returned a value that is not a well-formed humanish.adapter-score.v1 (non-empty namespace + status + numeric score + summary); dropped so the bundle stays verifiable.`);
43
57
  if (declared)
44
58
  failures.push(DECLARED_SCORER_MALFORMED);
45
59
  }
46
60
  }
47
61
  catch (error) {
48
62
  const detail = sanitize(error instanceof Error ? error.message : String(error));
49
- warnings.push(`${hookLabel}.score threw (${detail}); dropped so the bundle stays verifiable.`);
63
+ warnings.push(`scorer.score threw (${detail}); dropped so the bundle stays verifiable.`);
50
64
  if (declared)
51
65
  failures.push(declaredScorerThrew(detail));
52
66
  }
53
67
  }
54
- if (hooks.deriveFeedback) {
68
+ if (scorer?.deriveFeedback) {
55
69
  try {
56
- const candidates = await hooks.deriveFeedback(scoringContext);
70
+ const candidates = await scorer.deriveFeedback(scoringContext);
57
71
  const accepted = [];
58
72
  for (const candidate of Array.isArray(candidates) ? candidates : []) {
59
73
  const cleaned = scrubValue(candidate);
60
- if (isAdapterFeedbackCandidateShape(cleaned))
74
+ if (isAdapterFeedbackCandidate(cleaned))
61
75
  accepted.push(cleaned);
62
76
  else
63
- warnings.push(`${hookLabel}.deriveFeedback returned a candidate that is not a well-formed humanish.feedback-candidate.v1 (or its adapter block lacked a non-empty namespace + data record); dropped so the bundle stays verifiable.`);
77
+ warnings.push(`scorer.deriveFeedback returned a candidate that is not a well-formed humanish.feedback-candidate.v1 (or its adapter block lacked a non-empty namespace + data record); dropped so the bundle stays verifiable.`);
64
78
  }
65
79
  if (accepted.length > 0) {
66
80
  bundle.feedbackCandidates = [...bundle.feedbackCandidates, ...accepted];
67
81
  }
68
82
  }
69
83
  catch (error) {
70
- warnings.push(`${hookLabel}.deriveFeedback threw (${sanitize(error instanceof Error ? error.message : String(error))}); dropped so the bundle stays verifiable.`);
84
+ warnings.push(`scorer.deriveFeedback threw (${sanitize(error instanceof Error ? error.message : String(error))}); dropped so the bundle stays verifiable.`);
71
85
  }
72
86
  }
73
- if (hooks.deriveArtifacts) {
87
+ if (scorer?.deriveArtifacts) {
74
88
  try {
75
- const artifacts = await hooks.deriveArtifacts(scoringContext);
89
+ const artifacts = await scorer.deriveArtifacts(scoringContext);
76
90
  const accepted = [];
77
91
  for (const artifact of Array.isArray(artifacts) ? artifacts : []) {
78
92
  const cleaned = scrubValue(artifact);
79
93
  if (isAdapterArtifactShape(cleaned))
80
94
  accepted.push(cleaned);
81
95
  else
82
- warnings.push(`${hookLabel}.deriveArtifacts returned an artifact that is not a well-formed humanish.adapter-artifact.v1 (non-empty namespace + label + local path + supported kind); dropped so the bundle stays verifiable.`);
96
+ warnings.push(`scorer.deriveArtifacts returned an artifact that is not a well-formed humanish.adapter-artifact.v1 (non-empty namespace + label + local path + supported kind); dropped so the bundle stays verifiable.`);
83
97
  }
84
98
  if (accepted.length > 0) {
85
99
  bundle.adapterArtifacts = [...(bundle.adapterArtifacts ?? []), ...accepted];
86
100
  }
87
101
  }
88
102
  catch (error) {
89
- warnings.push(`${hookLabel}.deriveArtifacts threw (${sanitize(error instanceof Error ? error.message : String(error))}); dropped so the bundle stays verifiable.`);
103
+ warnings.push(`scorer.deriveArtifacts threw (${sanitize(error instanceof Error ? error.message : String(error))}); dropped so the bundle stays verifiable.`);
90
104
  }
91
105
  }
92
106
  return { failures };
93
107
  }
108
+ /**
109
+ * A feedback candidate a scorer returned, accepted at the seam: the bundle's candidate shape with a
110
+ * non-empty summary. The browser and terminal seams both use it, so a candidate either seam drops
111
+ * never reaches a bundle.
112
+ */
113
+ export function isAdapterFeedbackCandidate(value) {
114
+ return isRunFeedbackCandidate(value) && value.summary.trim().length > 0;
115
+ }
94
116
  export function adapterScoreFailureMessage(bundle) {
95
117
  return bundle.adapterScore?.status === "fail"
96
118
  ? `Adapter scorer failed the run: ${bundle.adapterScore.summary}`
97
119
  : undefined;
98
120
  }
99
121
  /**
100
- * Deep-freeze a structured clone so a loaded scorer sees a READ-ONLY bundle: it cannot mutate
122
+ * Deep-freeze a structured clone so a loaded scorer sees a read-only bundle: it cannot mutate
101
123
  * noSpend/cost/review in place to launder a verdict (which would defeat the costProbe-not-loadable
102
124
  * guarantee). A tamper attempt throws in the scorer's strict-mode ESM and is caught as a hook failure.
103
- * Legitimate read-only scoring is unaffected. The seam always stamps the REAL bundle, never this view.
125
+ * Legitimate read-only scoring is unaffected. The seam always stamps the real bundle, never this view.
104
126
  */
105
127
  export function frozenBundleView(bundle) {
106
128
  const clone = structuredClone(bundle);
@@ -115,62 +137,6 @@ export function frozenBundleView(bundle) {
115
137
  freeze(clone);
116
138
  return clone;
117
139
  }
118
- function isAdapterScoreShape(value) {
119
- return (typeof value === "object" &&
120
- value !== null &&
121
- !Array.isArray(value) &&
122
- value.schema === "humanish.adapter-score.v1" &&
123
- typeof value.namespace === "string" &&
124
- value.namespace.trim().length > 0 &&
125
- ["pass", "partial", "fail"].includes(value.status) &&
126
- typeof value.score === "number" &&
127
- Number.isFinite(value.score) &&
128
- typeof value.summary === "string" &&
129
- (value.data === undefined ||
130
- (typeof value.data === "object" &&
131
- value.data !== null &&
132
- !Array.isArray(value.data))));
133
- }
134
- function isAdapterFeedbackCandidateShape(value) {
135
- if (!isRecord(value))
136
- return false;
137
- const candidate = value;
138
- if (candidate.schema !== "humanish.feedback-candidate.v1" ||
139
- typeof candidate.id !== "string" ||
140
- typeof candidate.run_id !== "string" ||
141
- (candidate.stream_id !== undefined && typeof candidate.stream_id !== "string") ||
142
- typeof candidate.adapter_id !== "string" ||
143
- typeof candidate.scenario_id !== "string" ||
144
- typeof candidate.persona_id !== "string" ||
145
- !isFeedbackActor(candidate.actor) ||
146
- !isFeedbackSubstrate(candidate.substrate) ||
147
- !isFeedbackFailureOwner(candidate.failure_owner) ||
148
- typeof candidate.summary !== "string" ||
149
- candidate.summary.trim().length === 0 ||
150
- typeof candidate.expected !== "string" ||
151
- typeof candidate.actual !== "string" ||
152
- !Array.isArray(candidate.evidence) ||
153
- !candidate.evidence.every(isFeedbackEvidence) ||
154
- !isRecord(candidate.redaction) ||
155
- candidate.redaction.status !== "passed" ||
156
- typeof candidate.redaction.notes !== "string" ||
157
- !isFeedbackIdempotencyKey(candidate.idempotency_key) ||
158
- !isFeedbackNextState(candidate.proposed_next_state) ||
159
- !Array.isArray(candidate.acceptance_proof) ||
160
- !candidate.acceptance_proof.every((item) => typeof item === "string")) {
161
- return false;
162
- }
163
- if (candidate.adapter !== undefined) {
164
- const adapter = candidate.adapter;
165
- if (!isRecord(adapter) ||
166
- typeof adapter.namespace !== "string" ||
167
- adapter.namespace.trim().length === 0 ||
168
- !isRecord(adapter.data)) {
169
- return false;
170
- }
171
- }
172
- return true;
173
- }
174
140
  function isAdapterArtifactShape(value) {
175
141
  if (!isRecord(value))
176
142
  return false;
@@ -186,9 +152,6 @@ function isAdapterArtifactShape(value) {
186
152
  typeof artifact.note === "string" &&
187
153
  artifact.note.trim().length > 0);
188
154
  }
189
- function isRecord(value) {
190
- return typeof value === "object" && value !== null && !Array.isArray(value);
191
- }
192
155
  function isSafeRelativeArtifactPath(value) {
193
156
  return (value.trim().length > 0 &&
194
157
  !path.isAbsolute(value) &&
@@ -204,50 +167,3 @@ function isAdapterArtifactKind(value) {
204
167
  value === "filesystem" ||
205
168
  value === "summary");
206
169
  }
207
- function isFeedbackActor(value) {
208
- return (value === "codex-tui" ||
209
- value === "codex-exec" ||
210
- value === "codex-app-server" ||
211
- value === "computer-use" ||
212
- value === "synthetic-dry-run" ||
213
- value === "unknown");
214
- }
215
- function isFeedbackSubstrate(value) {
216
- return (value === "e2b-desktop" ||
217
- value === "local-desktop" ||
218
- value === "e2b-terminal" ||
219
- value === "local-filesystem" ||
220
- value === "codex-app-server" ||
221
- value === "unknown");
222
- }
223
- function isFeedbackFailureOwner(value) {
224
- return (value === "harness" ||
225
- value === "target-app" ||
226
- value === "actor" ||
227
- value === "environment" ||
228
- value === "unknown");
229
- }
230
- function isFeedbackNextState(value) {
231
- return (value === "watch" ||
232
- value === "adapter-hardening" ||
233
- value === "target-app-setup" ||
234
- value === "actor-auth" ||
235
- value === "setup-quality-review" ||
236
- value === "study-quality-review");
237
- }
238
- function isFeedbackEvidence(value) {
239
- if (!isRecord(value))
240
- return false;
241
- return (typeof value.path === "string" &&
242
- value.path.length > 0 &&
243
- !path.isAbsolute(value.path) &&
244
- !value.path.includes("://") &&
245
- !value.path.includes("..") &&
246
- (value.kind === "review" ||
247
- value.kind === "state" ||
248
- value.kind === "log" ||
249
- value.kind === "trace" ||
250
- value.kind === "screenshot" ||
251
- value.kind === "filesystem") &&
252
- typeof value.note === "string");
253
- }
@@ -2,22 +2,42 @@ import type { BrowserLabScoringContext } from "./adapter-extension.js";
2
2
  import type { TerminalProductScoringContext } from "../routes/terminal/types.js";
3
3
  import type { LabRoute } from "./plan.js";
4
4
  import type { RunAdapterArtifact, RunAdapterScore, RunFeedbackCandidate, RunScorerProvenance } from "../run/bundle.js";
5
- /** The read-model context a loaded scorer sees — the terminal or browser scoring context. The module
6
- * narrows it at runtime (`"product" in ctx` ⇒ terminal; `"backend" in ctx` ⇒ browser). */
5
+ /** The read-model context a loaded scorer sees: the terminal or browser scoring context. The module
6
+ * narrows it at runtime (`"product" in ctx` ⇒ terminal; `"route" in ctx` ⇒ browser). */
7
7
  export type AdapterScoringContext = TerminalProductScoringContext | BrowserLabScoringContext;
8
8
  /**
9
- * The adopter-facing scorer module contract (#316). Export any subset of these from a `.mjs` (or a
10
- * `.js`/`.cjs` whose package.json type matches) — named exports OR a single default object. The
11
- * loader wires ONLY these three; an exported `executor`/`env`/`provisionSubject`/`costProbe` is never
12
- * picked up (the whitelist is the scope guard). A module exporting NONE of them is a hard load error.
9
+ * The adopter-facing scorer module contract. Export any subset of these from a `.mjs` (or a
10
+ * `.js`/`.cjs` whose package.json type matches): named exports or a single default object. The
11
+ * loader wires only these three; an exported `executor`/`env`/`provisionSubject`/`costProbe` is never
12
+ * picked up (the whitelist is the scope guard). A module exporting none of them is a hard load error.
13
+ *
14
+ * `C` is the context `score` and `deriveFeedback` read: `BrowserLabScoringContext` for a scorer
15
+ * written for computer use and shared world, `TerminalProductScoringContext` for one written for
16
+ * terminal runs, or the default union for one that narrows at runtime.
13
17
  */
14
- export interface AdapterScorerModule {
15
- score?: (ctx: AdapterScoringContext) => RunAdapterScore | Promise<RunAdapterScore>;
16
- deriveFeedback?: (ctx: AdapterScoringContext) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
17
- /** Browser-route only; inert on the terminal route (TerminalProductLabHooks carries no artifacts seam). */
18
+ export interface AdapterScorerModule<C extends AdapterScoringContext = AdapterScoringContext> {
19
+ score?: (ctx: C) => RunAdapterScore | Promise<RunAdapterScore>;
20
+ deriveFeedback?: (ctx: C) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
21
+ /** Browser-route only; inert on the terminal route, whose TerminalScorer has no artifacts seam. */
18
22
  deriveArtifacts?: (ctx: BrowserLabScoringContext) => RunAdapterArtifact[] | Promise<RunAdapterArtifact[]>;
19
23
  }
20
- type AdapterScorerLoadErrorCode = "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
24
+ /**
25
+ * A scorer written for computer use and shared world, as `RunLabOptions.scorer` takes it. Those
26
+ * routes pass the browser context; another route that calls it passes a context it was not written
27
+ * for. The call states the kind, so the module itself needs no cast.
28
+ */
29
+ export declare function browserScorer(scorer: AdapterScorerModule<BrowserLabScoringContext>): AdapterScorerModule;
30
+ /** A scorer written for terminal runs, as `RunLabOptions.scorer` takes it (see browserScorer). */
31
+ export declare function terminalScorer(scorer: AdapterScorerModule<TerminalProductScoringContext>): AdapterScorerModule;
32
+ /**
33
+ * The scorer as a computer-use or shared-world run calls it, with the browser context. The caller
34
+ * chose the context it wrote the scorer for; only the route knows which context it passes, so the
35
+ * narrowing is here. A terminal-typed scorer on a browser route reads fields the context lacks.
36
+ */
37
+ export declare function browserRouteScorer(scorer: AdapterScorerModule): AdapterScorerModule<BrowserLabScoringContext>;
38
+ /** The scorer as a terminal run calls it, with the terminal context (see browserRouteScorer). */
39
+ export declare function terminalRouteScorer(scorer: AdapterScorerModule): AdapterScorerModule<TerminalProductScoringContext>;
40
+ type AdapterScorerLoadErrorCode = "HUMANISH_STUDY_SCORER_BAD_REF" | "HUMANISH_STUDY_SCORER_NOT_FOUND" | "HUMANISH_STUDY_SCORER_LOAD_FAILED" | "HUMANISH_STUDY_SCORER_NO_HOOKS" | "HUMANISH_STUDY_SCORER_UNSUPPORTED_BACKEND";
21
41
  export type AdapterScorerLoadResult = {
22
42
  ok: true;
23
43
  hooks: AdapterScorerModule;
@@ -32,7 +52,7 @@ export type AdapterScorerLoadResult = {
32
52
  /**
33
53
  * Resolve + load a config-declared scorer module. Resolution clones scenario.ref exactly
34
54
  * (prepareSelectedOutputDirectory → cwd-clamp → readContainedRegularFile), then `import()`s the
35
- * entry file in a BROAD try/catch. The digest is over the readContainedRegularFile ENTRY bytes.
55
+ * entry file in a broad try/catch. The digest is over the readContainedRegularFile entry bytes.
36
56
  */
37
57
  export declare function loadAdapterScorer(args: {
38
58
  cwd: string;
@@ -1,38 +1,62 @@
1
- // #316 — CLI-loadable adopter scorer. Resolve `review.scorer.ref` / `--scorer` to an out-of-tree
2
- // scorer module, load it fail-closed (typed error + exit 2, PRE-SPEND), and pick off ONLY the
1
+ // CLI-loadable adopter scorer. Resolve `review.scorer.ref` / `--scorer` to an out-of-tree
2
+ // scorer module, load it fail-closed (typed error + exit 2, before any spend), and pick off only the
3
3
  // whitelisted read-model hooks {score, deriveFeedback, deriveArtifacts}. `costProbe` is deliberately
4
- // NOT loadable — an injected provider cost line overwrites the core-measured one and can forge a
4
+ // not loadable: an injected provider cost line overwrites the core-measured one and can forge a
5
5
  // satisfied no-spend proof, so it stays library-only.
6
6
  //
7
- // TRUST MODEL (stated plainly, no overclaims): the party who writes `review.scorer.ref` is the party
8
- // who runs `humanish lab run` in their own checkout — identical trust to humanish.lab.yml or a
9
- // package.json script. #316 adds ZERO new execution capability; it relocates WHERE the reference is
10
- // declared. Containment is ENTRY-FILE-ONLY: `readContainedRegularFile` blocks abs/`..`/symlink/
7
+ // Trust model: the party who writes `review.scorer.ref` is the party
8
+ // who runs `humanish lab run` in their own checkout: identical trust to humanish.lab.yml or a
9
+ // package.json script. The loader adds no new execution capability; it relocates where the reference is
10
+ // declared. Containment is entry-file-only: `readContainedRegularFile` blocks abs/`..`/symlink/
11
11
  // hardlink/realpath-escape/TOCTOU on the entry module, but `import()` then executes the transitive
12
12
  // graph + npm deps with no clamp, and `import()` runs top-level module code before any whitelist
13
- // check. The whitelist bounds the WIRED HOOK SURFACE, not arbitrary import-time code; the
13
+ // check. The whitelist bounds the wired hook surface and does not cover import-time code; the
14
14
  // trusted-in-process boundary is the actual safety carrier. The seam's output re-scrub is a
15
- // best-effort denylist, NOT containment. `review.scorer.ref` entries are executable code — review a
15
+ // best-effort denylist that provides no containment. `review.scorer.ref` entries are executable code, so review a
16
16
  // PR that adds one as code, not config.
17
17
  import { realpath } from "node:fs/promises";
18
18
  import path from "node:path";
19
19
  import { pathToFileURL } from "node:url";
20
20
  import { digestText, redactText } from "../evidence/redaction.js";
21
21
  import { prepareSelectedOutputDirectory, readContainedRegularFile, } from "../run/contained-output.js";
22
- /** The routes whose hooks bag can carry the loaded scorer. A declared scorer on ANY other route
23
- * (scripted or preview) aborts at load — a gate that cannot run must never green-pass. */
22
+ /**
23
+ * A scorer written for computer use and shared world, as `RunLabOptions.scorer` takes it. Those
24
+ * routes pass the browser context; another route that calls it passes a context it was not written
25
+ * for. The call states the kind, so the module itself needs no cast.
26
+ */
27
+ export function browserScorer(scorer) {
28
+ return scorer;
29
+ }
30
+ /** A scorer written for terminal runs, as `RunLabOptions.scorer` takes it (see browserScorer). */
31
+ export function terminalScorer(scorer) {
32
+ return scorer;
33
+ }
34
+ /**
35
+ * The scorer as a computer-use or shared-world run calls it, with the browser context. The caller
36
+ * chose the context it wrote the scorer for; only the route knows which context it passes, so the
37
+ * narrowing is here. A terminal-typed scorer on a browser route reads fields the context lacks.
38
+ */
39
+ export function browserRouteScorer(scorer) {
40
+ return scorer;
41
+ }
42
+ /** The scorer as a terminal run calls it, with the terminal context (see browserRouteScorer). */
43
+ export function terminalRouteScorer(scorer) {
44
+ return scorer;
45
+ }
46
+ /** The routes that can run the loaded scorer. A declared scorer on any other route
47
+ * (scripted or preview) aborts at load: a gate that cannot run must never green-pass. */
24
48
  const SCORER_CAPABLE_ROUTES = new Set([
25
49
  "terminal",
26
50
  "computer-use",
27
51
  "shared-world",
28
52
  ]);
29
- /** `.mjs` is required-canonical; `.js`/`.cjs` accepted but the module system is the adopter repo's
30
- * package.json `type`. `.ts` is rejected — the compiled `dist/` CLI ships no TypeScript loader. */
53
+ /** `.mjs` is the recommended extension; `.js`/`.cjs` accepted but the module system is the adopter repo's
54
+ * package.json `type`. `.ts` is rejected: the compiled `dist/` CLI ships no TypeScript loader. */
31
55
  const SCORER_EXTENSIONS = new Set([".mjs", ".js", ".cjs"]);
32
56
  /**
33
57
  * Resolve + load a config-declared scorer module. Resolution clones scenario.ref exactly
34
58
  * (prepareSelectedOutputDirectory → cwd-clamp → readContainedRegularFile), then `import()`s the
35
- * entry file in a BROAD try/catch. The digest is over the readContainedRegularFile ENTRY bytes.
59
+ * entry file in a broad try/catch. The digest is over the readContainedRegularFile entry bytes.
36
60
  */
37
61
  export async function loadAdapterScorer(args) {
38
62
  const { route, source } = args;
@@ -40,25 +64,25 @@ export async function loadAdapterScorer(args) {
40
64
  ok: false,
41
65
  error: { code, message },
42
66
  });
43
- // A declared gate that cannot run on this route must ABORT (never silently green-pass).
67
+ // A declared gate that cannot run on this route must abort (never silently green-pass).
44
68
  if (!SCORER_CAPABLE_ROUTES.has(route)) {
45
- return fail("HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND", `review.scorer.ref is declared but this lab resolves to the ${route} route, which has no adopter-scorer seam. A declared scorer that cannot run must fail closed rather than pass silently — declare it on a terminal, computer-use or shared-world lab.`);
69
+ return fail("HUMANISH_STUDY_SCORER_UNSUPPORTED_BACKEND", `review.scorer.ref is set, but this study runs on the ${route} route, which cannot run a scorer. The run stops here so the scorer is not silently skipped. Use it with a terminal, computer-use or shared-world study, or remove review.scorer.ref.`);
46
70
  }
47
71
  const trimmed = args.ref.trim();
48
72
  if (!trimmed) {
49
- return fail("HUMANISH_LAB_SCORER_BAD_REF", "review.scorer.ref must be a non-empty repo-relative path ending in .mjs (recommended), .js, or .cjs.");
73
+ return fail("HUMANISH_STUDY_SCORER_BAD_REF", "review.scorer.ref must be a non-empty repo-relative path ending in .mjs (recommended), .js, or .cjs.");
50
74
  }
51
- // Provenance is recorded repo-relative — an absolute ref (even one that happens to land inside cwd)
75
+ // Provenance is recorded repo-relative: an absolute ref (even one that happens to land inside cwd)
52
76
  // is rejected up front rather than silently rewritten to its in-tree relative form.
53
77
  if (path.isAbsolute(trimmed)) {
54
- return fail("HUMANISH_LAB_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must be a repo-relative path, not absolute — provenance is recorded repo-relative.`);
78
+ return fail("HUMANISH_STUDY_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must be a path relative to the project, not an absolute path, because the run records it relative to the project.`);
55
79
  }
56
80
  const ext = path.extname(trimmed).toLowerCase();
57
81
  if (ext === ".ts") {
58
- return fail("HUMANISH_LAB_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" ends in .ts, but the shipped CLI runs compiled JS with no TypeScript loader. Precompile to .mjs (recommended) or .js/.cjs.`);
82
+ return fail("HUMANISH_STUDY_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" ends in .ts, but the shipped CLI runs compiled JS with no TypeScript loader. Precompile to .mjs (recommended) or .js/.cjs.`);
59
83
  }
60
84
  if (!SCORER_EXTENSIONS.has(ext)) {
61
- return fail("HUMANISH_LAB_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must be a repo-relative PATH ending in .mjs (recommended), .js, or .cjs — an id-style ref is not supported.`);
85
+ return fail("HUMANISH_STUDY_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must be a path relative to the project ending in .mjs (recommended), .js or .cjs.`);
62
86
  }
63
87
  // Root token: realpath(cwd) → prepareSelectedOutputDirectory(dirname, cwd). Mirrors scenario.ref.
64
88
  const physicalCwd = await realpath(path.resolve(args.cwd));
@@ -67,18 +91,18 @@ export async function loadAdapterScorer(args) {
67
91
  const absolutePath = path.resolve(root.physicalPath, trimmed);
68
92
  const relative = path.relative(root.physicalPath, absolutePath);
69
93
  if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) {
70
- return fail("HUMANISH_LAB_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must stay inside the target cwd — provenance is recorded repo-relative and an escaping/absolute path (a cwd parent, node_modules above cwd, an absolute path) cannot be.`);
94
+ return fail("HUMANISH_STUDY_SCORER_BAD_REF", `review.scorer.ref "${trimmed}" must stay inside the project directory, because the run records it relative to the project; a path into a parent directory cannot be recorded that way.`);
71
95
  }
72
96
  const relPosix = relative.split(path.sep).join("/");
73
- // Fail-closed containment gate on the ENTRY file only: rejects symlink, nlink>1, realpath-escape,
97
+ // Fail-closed containment gate on the entry file only: rejects symlink, nlink>1, realpath-escape,
74
98
  // TOCTOU. Its returned bytes are the digest input.
75
99
  const bytes = await readContainedRegularFile(root, relPosix);
76
100
  if (!bytes) {
77
- return fail("HUMANISH_LAB_SCORER_NOT_FOUND", `review.scorer.ref "${trimmed}" could not be read as a contained regular file (${relPosix}). A scorer must be a regular file inside the target cwd — no symlink, no hardlink, no realpath escape.`);
101
+ return fail("HUMANISH_STUDY_SCORER_NOT_FOUND", `review.scorer.ref "${trimmed}" could not be read as a regular file inside the project (${relPosix}). Use a plain file there: not a symlink or a hard link, and not a path that resolves outside the project.`);
78
102
  }
79
103
  const digest = digestText(bytes.toString("utf8"));
80
- // Import the entry module in a BROAD try/catch (ERR_MODULE_NOT_FOUND / SyntaxError / ERR_REQUIRE_ESM
81
- // / top-level throw). import() executes the transitive graph — the cwd clamp guards only the ENTRY
104
+ // Import the entry module in a broad try/catch (ERR_MODULE_NOT_FOUND / SyntaxError / ERR_REQUIRE_ESM
105
+ // / top-level throw). import() executes the transitive graph, and the cwd clamp guards only the entry
82
106
  // file; out-of-tree/transitive code is acceptable only because of the trust boundary above.
83
107
  let mod;
84
108
  try {
@@ -90,12 +114,12 @@ export async function loadAdapterScorer(args) {
90
114
  const hint = /ERR_REQUIRE_ESM|import statement outside a module|Cannot use import statement|Unexpected (?:token|identifier)|SyntaxError/i.test(detail)
91
115
  ? ' Use a .mjs entry file, or set "type": "module" in the nearest package.json.'
92
116
  : "";
93
- return fail("HUMANISH_LAB_SCORER_LOAD_FAILED", `review.scorer.ref "${trimmed}" failed to load: ${redactText(detail)}.${hint}`);
117
+ return fail("HUMANISH_STUDY_SCORER_LOAD_FAILED", `review.scorer.ref "${trimmed}" failed to load: ${redactText(detail)}.${hint}`);
94
118
  }
95
- // mod.default ?? mod, then pick off ONLY the whitelist. An exported executor/env/costProbe is never
96
- // wired — the whitelist is the scope guard. `exports` records the hooks ACTUALLY WIRED for this
119
+ // mod.default ?? mod, then pick off only the whitelist. An exported executor/env/costProbe is never
120
+ // wired; the whitelist is the scope guard. `exports` records the hooks actually wired for this
97
121
  // backend: deriveArtifacts is browser-only, so on the terminal route it is neither wired nor
98
- // recorded (a scorer that exported ONLY deriveArtifacts there wires nothing and fails closed below,
122
+ // recorded (a scorer that exported only deriveArtifacts there wires nothing and fails closed below,
99
123
  // never a silent no-op).
100
124
  const picked = (mod.default ?? mod);
101
125
  const terminalRoute = route === "terminal";
@@ -115,9 +139,9 @@ export async function loadAdapterScorer(args) {
115
139
  }
116
140
  if (exports.length === 0) {
117
141
  const artifactsOnly = terminalRoute && typeof picked.deriveArtifacts === "function";
118
- return fail("HUMANISH_LAB_SCORER_NO_HOOKS", artifactsOnly
142
+ return fail("HUMANISH_STUDY_SCORER_NO_HOOKS", artifactsOnly
119
143
  ? `review.scorer.ref "${trimmed}" exported only deriveArtifacts, which is browser-only and inert on the terminal route. Export score and/or deriveFeedback for a terminal-product scorer.`
120
- : `review.scorer.ref "${trimmed}" loaded but exported none of the adopter-scorer hooks (score, deriveFeedback, deriveArtifacts). Export at least one (named, or on a single default object). costProbe is intentionally NOT loadable.`);
144
+ : `review.scorer.ref "${trimmed}" loaded but exports none of score, deriveFeedback or deriveArtifacts. Export at least one, as a named export or on a default object. costProbe cannot be loaded from a scorer file.`);
121
145
  }
122
146
  const provenance = {
123
147
  schema: "humanish.scorer-provenance.v1",