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
@@ -9,12 +9,12 @@
9
9
  // The step executor's `page` is typed as the narrow structural ScriptedPageLike instead of
10
10
  // playwright's Page (browserPersonaPageState already took { evaluate, url }; E2BDesktopLike is
11
11
  // the same seam pattern). playwright's real Page satisfies it; tests inject fakes and run
12
- // the REAL step executor at $0 with zero browser dependence. playwright-core stays the lazy
12
+ // the real step executor at $0 with zero browser dependence. playwright-core stays the lazy
13
13
  // production default behind launchPlaywrightChromium.
14
14
  //
15
- // Spend posture: nothing in this module can spend provider money — no provider client is
15
+ // Spend posture: nothing in this module can spend provider money: no provider client is
16
16
  // importable from this code path. tokenUsage on every projected trace records zeros as an
17
- // affirmative $0 declaration that is TRUE by mechanism.
17
+ // affirmative $0 declaration that is true by mechanism.
18
18
  import { stat } from "node:fs/promises";
19
19
  import path from "node:path";
20
20
  import { CHROMIUM_EVIDENCE_HYGIENE_FLAGS } from "../../evidence/browser-hygiene.js";
@@ -24,7 +24,7 @@ import { ACTOR_TRACE_SCHEMA, SCRIPTED_BROWSER_CAPABILITIES, } from "../contract.
24
24
  import { buildBlockedBrowserPersonaSteps, buildBrowserTrace, captureBlockedStepScreenshot, compactBrowserError, executeBrowserPersonaStep, probeAppUrl, sanitizeBrowserEvidenceUrl, screenshotPathForBrowserStep, surfaceScreenshotPath, tracePathForBrowserSurface, } from "./steps.js";
25
25
  import { LOOPBACK_EVIDENCE_URL_POLICY, } from "./types.js";
26
26
  /** Production default: lazy playwright-core import + chromium.launch, exactly as the driver
27
- * always did. Kept in ONE place so the optional peer is touched by exactly one code path. */
27
+ * always did. Kept in one place so the optional peer is touched by exactly one code path. */
28
28
  async function launchPlaywrightChromium(args) {
29
29
  const { chromium } = await import("playwright-core");
30
30
  const browser = await chromium.launch({
@@ -50,19 +50,19 @@ class ScriptedJourneyTimeoutError extends Error {
50
50
  }
51
51
  }
52
52
  /**
53
- * Run the scripted journey for ONE surface and return native capture + ActorTrace projection.
53
+ * Run the scripted journey for one surface and return native capture + ActorTrace projection.
54
54
  *
55
55
  * Completion semantics (the contract the projection tests pin):
56
56
  * - every step executed, every assertion passed, HTTP probe ok -> passed / goal_satisfied
57
- * (the scenario's expect blocks ARE the success predicate; a pass claims "the app still
57
+ * (the scenario's expect blocks are the success predicate; a pass claims "the app still
58
58
  * affords this exact journey", nothing about user behavior);
59
59
  * - a step's expectation evaluated false, a step target missing/unactionable, or an
60
- * unreachable subject -> failed / step_failed (the harness executed faithfully; the SUBJECT
61
- * did not satisfy the script — distinct from actor_error/harness_error);
60
+ * unreachable subject -> failed / step_failed (the harness executed faithfully; the subject
61
+ * did not satisfy the script, distinct from actor_error/harness_error);
62
62
  * - journey exceeded timeoutMs -> timed_out / timed_out;
63
63
  * - browser launch/import crash -> failed / harness_error;
64
- * - gave_up / blocked_approval are UNREACHABLE from this actor (no persona patience, no
65
- * approvals exist on a deterministic replay) — asserted in tests.
64
+ * - gave_up / blocked_approval are unreachable from this actor (no persona patience, no
65
+ * approvals exist on a deterministic replay), asserted in tests.
66
66
  */
67
67
  export async function runScriptedBrowserSession(options) {
68
68
  assertScriptedSessionPathIds(options);
@@ -107,7 +107,7 @@ export async function runScriptedBrowserSessionInPreparedRoot(options, preparedA
107
107
  trace,
108
108
  };
109
109
  };
110
- // Launch FIRST: a browser that cannot start is a harness failure, never subject evidence.
110
+ // Launch first: a browser that cannot start is a harness failure, never subject evidence.
111
111
  let browser;
112
112
  try {
113
113
  browser = await launch({ browserCommand, timeoutMs: options.timeoutMs });
@@ -289,7 +289,7 @@ async function runScriptedJourney(args) {
289
289
  };
290
290
  }
291
291
  /** Race one step against the journey's remaining wall-clock budget. A hanging step rejects
292
- * with the timeout error; the journey's catch path then records honest blocked steps. */
292
+ * with the timeout error; the journey's catch path then records the remaining steps as blocked. */
293
293
  async function withJourneyDeadline(promise, deadline, timeoutMs) {
294
294
  const remaining = deadline - Date.now();
295
295
  if (remaining <= 0) {
@@ -353,7 +353,7 @@ async function persistScriptedFailureCapture(args) {
353
353
  };
354
354
  }
355
355
  /** Project one surface capture into humanish.actor-trace.v1. screenshotRefs are attached only
356
- * for frames that actually exist on disk (honest counts; blocked-not-executed steps name a
356
+ * for frames that actually exist on disk (so counts match disk; blocked-not-executed steps name a
357
357
  * path that was never written). */
358
358
  async function projectScriptedActorTrace(args) {
359
359
  const writtenScreenshots = new Set();
@@ -371,7 +371,7 @@ async function projectScriptedActorTrace(args) {
371
371
  const items = args.capture.steps.map((step) => {
372
372
  const assertions = step.assertions ?? [];
373
373
  assertionCount += assertions.length;
374
- const assertionLines = assertions.map((assertion) => `${assertion.id}: ${assertion.status} — ${assertion.reason}`);
374
+ const assertionLines = assertions.map((assertion) => `${assertion.id}: ${assertion.status} (${assertion.reason})`);
375
375
  return {
376
376
  id: step.id,
377
377
  kind: "ui_action",
@@ -401,7 +401,7 @@ async function projectScriptedActorTrace(args) {
401
401
  status: args.status,
402
402
  completionReason: args.completionReason,
403
403
  reason: redactText(args.reason),
404
- // No session/model ids exist on a deterministic replay — absence declared by omission.
404
+ // No session/model ids exist on a deterministic replay; absence declared by omission.
405
405
  ids: {},
406
406
  counts: {
407
407
  steps: args.journey.steps.length,
@@ -412,7 +412,7 @@ async function projectScriptedActorTrace(args) {
412
412
  screenshots: writtenScreenshots.size,
413
413
  },
414
414
  items,
415
- // Affirmative $0 declaration, TRUE by mechanism: no provider client is importable from
415
+ // Affirmative $0 declaration, true by mechanism: no provider client is importable from
416
416
  // this code path, so zeros are a recorded fact, not an estimate.
417
417
  tokenUsage: { input: 0, output: 0, total: 0, costUsd: 0 },
418
418
  capabilities: SCRIPTED_BROWSER_CAPABILITIES,
@@ -1,5 +1,5 @@
1
1
  // Find a Chromium binary on the host for the scripted browser: HUMANISH_BROWSER_COMMAND first, then
2
- // the macOS Chrome path, then google-chrome, chromium and chromium-browser on PATH. A candidate
2
+ // the macOS Chrome path, then google-chrome, chromium and chromium-browser on `PATH`. A candidate
3
3
  // counts only if `--version` runs.
4
4
  import { execFile } from "node:child_process";
5
5
  import path from "node:path";
@@ -1,6 +1,7 @@
1
1
  // Parse a scenario's `browser.steps` into a BrowserPersonaJourney: the actions, text assertions and
2
2
  // expectations the scripted browser runs. The journey is the actor's whole behavior.
3
3
  import path from "node:path";
4
+ import { isRecord } from "../../run/type-guards.js";
4
5
  export function parseBrowserPersonaJourneyFromScenario(args) {
5
6
  if (!isRecord(args.raw)) {
6
7
  return {};
@@ -86,7 +87,16 @@ function parseBrowserPersonaStep(rawStep, index) {
86
87
  const selector = stringValue(source.selector);
87
88
  const pathValue = stringValue(source.path);
88
89
  const value = stringValue(source.value);
90
+ const key = stringValue(source.key);
89
91
  const expectation = browserStepExpectationValue(source.expect ?? source.expectation);
92
+ if (action === "press" && !key) {
93
+ return { failure: `${id} press action requires key (for example Enter).` };
94
+ }
95
+ if (action !== "press" && "key" in source) {
96
+ return {
97
+ failure: `${id} sets key, which only a press step sends. Supported actions: ${SUPPORTED_ACTIONS}.`,
98
+ };
99
+ }
90
100
  if (action === "fill" && !selector) {
91
101
  return { failure: `${id} fill action requires selector.` };
92
102
  }
@@ -105,12 +115,14 @@ function parseBrowserPersonaStep(rawStep, index) {
105
115
  ...(pathValue === undefined ? {} : { path: pathValue }),
106
116
  ...(selector === undefined ? {} : { selector }),
107
117
  ...(value === undefined ? {} : { value }),
118
+ ...(key === undefined ? {} : { key }),
108
119
  },
109
120
  };
110
121
  }
111
122
  function hasInlineBrowserSteps(value) {
112
123
  return Array.isArray(value) && value.some((entry) => isRecord(entry) && isRecord(entry.browser));
113
124
  }
125
+ const SUPPORTED_ACTIONS = "goto, fill, click, press, assertText, waitForText, waitForSelector";
114
126
  function browserPersonaActionValue(value) {
115
127
  if (typeof value !== "string") {
116
128
  return null;
@@ -121,8 +133,10 @@ function browserPersonaActionValue(value) {
121
133
  .replace(/[-_\s]+/g, "");
122
134
  if (normalized === "goto" || normalized === "open" || normalized === "navigate")
123
135
  return "goto";
124
- if (normalized === "click" || normalized === "press")
136
+ if (normalized === "click")
125
137
  return "click";
138
+ if (normalized === "press")
139
+ return "press";
126
140
  if (normalized === "fill" || normalized === "type")
127
141
  return "fill";
128
142
  if (normalized === "asserttext" || normalized === "expecttext")
@@ -152,9 +166,6 @@ function browserStepExpectationValue(value) {
152
166
  };
153
167
  return Object.keys(expectation).length === 0 ? undefined : expectation;
154
168
  }
155
- function isRecord(value) {
156
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
157
- }
158
169
  function stringValue(value) {
159
170
  return typeof value === "string" && value.trim() ? value.trim() : undefined;
160
171
  }
@@ -52,6 +52,24 @@ export async function executeBrowserPersonaStep(args) {
52
52
  await target.click({ timeout: stepTimeoutMs });
53
53
  await args.page.waitForTimeout(300);
54
54
  }
55
+ else if (args.step.action === "press") {
56
+ if (!args.step.key) {
57
+ throw new Error(`${args.step.id} press step is missing key`);
58
+ }
59
+ // With a selector, Playwright focuses that element first; without one, the key goes to
60
+ // whatever has focus, such as the input a fill step just typed into.
61
+ if (args.step.selector) {
62
+ const target = args.page.locator(args.step.selector).first();
63
+ if ((await target.count()) === 0) {
64
+ throw new Error(`${args.step.id} press step found no target`);
65
+ }
66
+ await target.press(args.step.key, { timeout: stepTimeoutMs });
67
+ }
68
+ else {
69
+ await args.page.keyboard.press(args.step.key);
70
+ }
71
+ await args.page.waitForTimeout(300);
72
+ }
55
73
  else if (args.step.action === "assertText" || args.step.action === "waitForText") {
56
74
  const expectedText = args.step.expectation?.text ?? args.step.value;
57
75
  if (!expectedText) {
@@ -158,7 +176,7 @@ async function waitForPageText(page, expectedText, timeoutMs) {
158
176
  }
159
177
  export function buildBlockedBrowserPersonaSteps(args) {
160
178
  // The journey never ran, so no screenshot was written for these steps. The
161
- // failure IS the evidence: keep the blocked status + reason, but omit the
179
+ // failure is the evidence: keep the blocked status + reason, but omit the
162
180
  // screenshot reference so the bundle never claims an artifact that does not
163
181
  // exist (otherwise verify's missingLocalEvidenceArtifacts fails closed on
164
182
  // evidence that was never meant to exist).
@@ -6,6 +6,10 @@ export interface ScriptedLocatorLike {
6
6
  click(options?: {
7
7
  timeout?: number;
8
8
  }): Promise<void>;
9
+ /** Focuses the element and presses the key, as Playwright's Locator.press does. */
10
+ press(key: string, options?: {
11
+ timeout?: number;
12
+ }): Promise<void>;
9
13
  count(): Promise<number>;
10
14
  waitFor(options?: {
11
15
  state?: "visible";
@@ -21,6 +25,10 @@ export interface ScriptedPageLike {
21
25
  timeout?: number;
22
26
  }): Promise<unknown>;
23
27
  locator(selector: string): ScriptedLocatorLike;
28
+ /** Presses a key on whatever element has focus. */
29
+ keyboard: {
30
+ press(key: string): Promise<void>;
31
+ };
24
32
  waitForTimeout(ms: number): Promise<void>;
25
33
  waitForFunction(fn: string, arg: unknown, options?: {
26
34
  timeout?: number;
@@ -83,7 +91,7 @@ export interface BrowserSurfaceCapture {
83
91
  surface: BrowserSurface;
84
92
  tracePath: string;
85
93
  }
86
- export type BrowserPersonaAction = "goto" | "click" | "fill" | "assertText" | "waitForText" | "waitForSelector";
94
+ export type BrowserPersonaAction = "goto" | "click" | "press" | "fill" | "assertText" | "waitForText" | "waitForSelector";
87
95
  export interface BrowserPersonaAssertionCapture {
88
96
  id: string;
89
97
  reason: string;
@@ -100,7 +108,7 @@ export interface BrowserPersonaStepCapture {
100
108
  /**
101
109
  * Path to the step screenshot the producer actually wrote. Omitted for blocked
102
110
  * steps where the failure itself is the recorded evidence and no screenshot was
103
- * written — the bundle must not reference an artifact that does not exist. A step that
111
+ * written: the bundle must not reference an artifact that does not exist. A step that
104
112
  * ran and attempted a screenshot keeps this even when its assertions failed, so a broken
105
113
  * producer still fails verify.
106
114
  */
@@ -122,6 +130,8 @@ export interface BrowserPersonaStepManifest {
122
130
  path?: string;
123
131
  selector?: string;
124
132
  value?: string;
133
+ /** A press step's key, in Playwright's key syntax ("Enter", "Tab", "Control+A"). */
134
+ key?: string;
125
135
  }
126
136
  export interface BrowserPersonaJourney {
127
137
  goal: string;
@@ -14,7 +14,7 @@ export interface StopWhen {
14
14
  any: StopWhenRule[];
15
15
  }
16
16
  /**
17
- * A declared observation window (#510): once `when` matches (or at the start, when `when` is
17
+ * A declared observation window: once `when` matches (or at the start, when `when` is
18
18
  * absent), the harness holds the page for `ms`, captures a frame every `everyMs`, takes no action
19
19
  * and requests no model turn, then hands control back to the participant (`then: continue`) or
20
20
  * ends the session (`then: stop`). Bounded by the session budget: a window that would outlast it
@@ -1,3 +1,4 @@
1
+ import { isRecord } from "../run/type-guards.js";
1
2
  export function evaluateStopWhen(stopWhen, observation) {
2
3
  if (!stopWhen)
3
4
  return undefined;
@@ -60,6 +61,3 @@ function valueAtPath(source, path) {
60
61
  }
61
62
  return current;
62
63
  }
63
- function isRecord(value) {
64
- return typeof value === "object" && value !== null && !Array.isArray(value);
65
- }
@@ -1,13 +1,16 @@
1
1
  import { FinishedRun } from "../run/run.js";
2
2
  import type { AnalysisConfig } from "./types.js";
3
- import { runAutomaticStudyAnalysis, type AutomaticAnalysisDeps } from "./automatic.js";
3
+ import type { LabDeps } from "../lab/lab-deps.js";
4
+ import type { LabEvent } from "../lab/run-lab-events.js";
5
+ import { type AutomaticAnalysisDeps } from "./automatic.js";
4
6
  import type { AutomaticAnalysisOutcome } from "./job.js";
5
- export interface AutomaticAnalysisHooks {
6
- /** Provider/test dependencies apply only to analysis, never to the participant. */
7
- deps?: AutomaticAnalysisDeps;
8
- /** Called after the source is finalized; the returned cleanup always runs. */
9
- onStart?: () => void | (() => void);
10
- run?: typeof runAutomaticStudyAnalysis;
7
+ /** What a route's input gives its analysis: the test's runner and deps, the signal and onEvent. */
8
+ export interface AnalysisInput {
9
+ readonly deps?: Pick<LabDeps, "analysis">;
10
+ /** Cancels the analysis only. */
11
+ readonly analysisSignal?: AbortSignal;
12
+ /** Receives analysis-started and analysis-finished. */
13
+ readonly emit?: (event: LabEvent) => void;
11
14
  }
12
15
  export interface AutomaticAnalysisResult {
13
16
  automaticAnalysis?: AutomaticAnalysisOutcome;
@@ -23,11 +26,13 @@ export declare function completeAutomaticAnalysis<T extends {
23
26
  cwd: string;
24
27
  runId: string;
25
28
  dryRun: boolean;
26
- }>(result: T, finished: FinishedRun | undefined, config: AnalysisConfig | undefined, hooks?: AutomaticAnalysisHooks, { trigger, preferLargerOutput, }?: {
29
+ }>(result: T, finished: FinishedRun | undefined, config: AnalysisConfig | undefined, input: AnalysisInput | undefined, { trigger, preferLargerOutput, refusal, }?: {
27
30
  /** "default" when the lab declared no analysis; its missing-key skip is not a failure. */
28
31
  trigger?: "default" | "explicit";
29
32
  /** The lab omitted an output limit, so a larger one may be used within the admission budget. */
30
33
  preferLargerOutput?: boolean;
34
+ /** The route's reason not to analyze this run; see AutomaticAnalysisDeps.refusal. */
35
+ refusal?: AutomaticAnalysisDeps["refusal"];
31
36
  }): Promise<T & AutomaticAnalysisResult>;
32
37
  /**
33
38
  * True when an analysis the lab never declared was refused because its conservative estimate is
@@ -1,12 +1,12 @@
1
1
  import { physicalCwdOf, validatePreparedRunRootIdentity } from "../run/paths.js";
2
2
  import { FinishedRun } from "../run/run.js";
3
- import { runAutomaticStudyAnalysis } from "./automatic.js";
3
+ import { runAutomaticAnalysis } from "./automatic.js";
4
4
  /**
5
5
  * One post-completion boundary shared by all live recording producers. `finished` is the token
6
6
  * the producer's run scope issued when the run published its final bundle; without it, or when it
7
7
  * names another run than the result, there is no source to analyze.
8
8
  */
9
- export async function completeAutomaticAnalysis(result, finished, config, hooks, { trigger = "explicit", preferLargerOutput = false, } = {}) {
9
+ export async function completeAutomaticAnalysis(result, finished, config, input, { trigger = "explicit", preferLargerOutput = false, refusal, } = {}) {
10
10
  if (config === undefined)
11
11
  return result;
12
12
  const origin = trigger === "default" ? { automaticAnalysisTrigger: trigger } : {};
@@ -26,9 +26,12 @@ export async function completeAutomaticAnalysis(result, finished, config, hooks,
26
26
  };
27
27
  }
28
28
  const prepared = finished.paths;
29
- let cleanup = undefined;
29
+ const seams = input?.deps?.analysis;
30
+ const signal = input?.analysisSignal;
31
+ let started = false;
30
32
  try {
31
- cleanup = hooks?.onStart?.();
33
+ input?.emit?.({ type: "analysis-started" });
34
+ started = true;
32
35
  try {
33
36
  await validatePreparedRunRootIdentity(prepared);
34
37
  }
@@ -40,8 +43,10 @@ export async function completeAutomaticAnalysis(result, finished, config, hooks,
40
43
  };
41
44
  }
42
45
  const sourceCwd = physicalCwdOf(prepared);
43
- const automaticAnalysis = await (hooks?.run ?? runAutomaticStudyAnalysis)(sourceCwd, finished.runId, config, {
44
- ...hooks?.deps,
46
+ const automaticAnalysis = await (seams?.run ?? runAutomaticAnalysis)(sourceCwd, finished.runId, config, {
47
+ ...seams?.deps,
48
+ ...(signal === undefined ? {} : { signal }),
49
+ ...(refusal === undefined ? {} : { refusal }),
45
50
  preferLargerOutput,
46
51
  ...(trigger === "default" ? { defaultRequest: true } : {}),
47
52
  expectedRun: prepared,
@@ -58,10 +63,11 @@ export async function completeAutomaticAnalysis(result, finished, config, hooks,
58
63
  }
59
64
  finally {
60
65
  try {
61
- cleanup?.();
66
+ if (started)
67
+ input?.emit?.({ type: "analysis-finished" });
62
68
  }
63
69
  catch {
64
- /* Cleanup cannot erase accounting or the completed recording. */
70
+ /* A report cannot erase accounting or the completed recording. */
65
71
  }
66
72
  }
67
73
  }
@@ -19,7 +19,7 @@ export type LabAnalysis = LabAnalysisSettings & ({
19
19
  });
20
20
  /** The spend cap on an analysis the lab did not declare. */
21
21
  export declare const DEFAULT_ANALYSIS_MAX_COST_USD = 3;
22
- /** Called for parsed manifests AND direct library configs, before participant execution. */
22
+ /** Called for parsed manifests and direct library configs, before participant execution. */
23
23
  export declare function resolveAutomaticAnalysis(raw: unknown): {
24
24
  ok: true;
25
25
  config: AnalysisConfig | undefined;
@@ -24,7 +24,7 @@ const SENSITIVE_QUESTION = {
24
24
  };
25
25
  /** The spend cap on an analysis the lab did not declare. */
26
26
  export const DEFAULT_ANALYSIS_MAX_COST_USD = 3;
27
- /** Called for parsed manifests AND direct library configs, before participant execution. */
27
+ /** Called for parsed manifests and direct library configs, before participant execution. */
28
28
  export function resolveAutomaticAnalysis(raw) {
29
29
  if (raw === false)
30
30
  return { ok: true, config: undefined };
@@ -131,5 +131,5 @@ export function automaticAnalysisBudget(raw, route) {
131
131
  export function formatAutomaticAnalysisBudget(budget) {
132
132
  if (budget.provider === "codex")
133
133
  return `After live runs: Codex account analysis · ${budget.model} · separate restricted analyst with remote inference. Account limits apply; dollar cost and output-token ceiling are unknown. Set review.analysis: false to disable.`;
134
- return `After live runs: ${budget.trigger} analysis · ${budget.model} · separate $${budget.maxCostUsd} admission estimate limit (not a provider billing cap). Set review.analysis: false to disable.`;
134
+ return `After live runs: ${budget.trigger} analysis · ${budget.model} · refused before it starts if its estimate is over $${budget.maxCostUsd}; this is not a billing cap. Set review.analysis: false to disable.`;
135
135
  }
@@ -1,17 +1,23 @@
1
1
  import { type AnalyzeDeps } from "./service.js";
2
- import { type AutomaticAnalysisView, type AutomaticAnalysisOutcome, type AutomaticAnalysisCancellation } from "./job.js";
2
+ import { type AutomaticAnalysisView, type AutomaticAnalysisOutcome, type AutomaticAnalysisRefusal, type AutomaticAnalysisCancellation } from "./job.js";
3
3
  import { type AnalysisConfig } from "./types.js";
4
4
  export type { AutomaticAnalysisView, AutomaticAnalysisOutcome, AutomaticAnalysisCancellation, } from "./job.js";
5
5
  export type AutomaticAnalysisDeps = Omit<AnalyzeDeps, "analysisId" | "beforeDispatch"> & {
6
6
  /** A missing default key records a skip before admission, preserving a successful recording. */
7
7
  defaultRequest?: boolean;
8
+ /**
9
+ * A route's reason not to analyze this run, such as a local study whose cleanup is unconfirmed.
10
+ * It is checked after the job is claimed, so the skip is recorded where the CLI, the TUI and the
11
+ * Observer read it.
12
+ */
13
+ refusal?: () => AutomaticAnalysisRefusal | undefined;
8
14
  /** Expand an omitted output limit only within the existing admission budget. */
9
15
  preferLargerOutput?: boolean;
10
16
  };
11
17
  /** Small read-only TUI/CLI projection. Neither this nor Observer can resume a job. */
12
- export declare function readAutomaticStudyAnalysis(cwd: string, runId: string): Promise<AutomaticAnalysisView | undefined>;
13
- export declare function requestAutomaticStudyAnalysisCancellation(cwd: string, runId: string): Promise<AutomaticAnalysisCancellation>;
18
+ export declare function readAutomaticAnalysis(cwd: string, runId: string): Promise<AutomaticAnalysisView | undefined>;
19
+ export declare function requestAutomaticAnalysisCancellation(cwd: string, runId: string): Promise<AutomaticAnalysisCancellation>;
14
20
  /** One permanent claim per completed run, consumed even when preparation/cancellation fails.
15
21
  * Only the original producer calls this after all recording writes return.
16
22
  * No file reader, restart recovery, Observer poll or export calls this function. */
17
- export declare function runAutomaticStudyAnalysis(cwdInput: string, runId: string, configInput: AnalysisConfig, deps?: AutomaticAnalysisDeps): Promise<AutomaticAnalysisOutcome>;
23
+ export declare function runAutomaticAnalysis(cwdInput: string, runId: string, configInput: AnalysisConfig, deps?: AutomaticAnalysisDeps): Promise<AutomaticAnalysisOutcome>;
@@ -5,10 +5,10 @@ import { refreshObserver, analyzeRun, readCompletedAnalysisSource, resolveAnalys
5
5
  import { preferLargerAnalysisOutput, ANALYSIS_PROMPT_VERSION } from "./execute.js";
6
6
  import { captureEvidence } from "./evidence.js";
7
7
  import { hashAnalysisValue } from "./validation.js";
8
- import { claimAutomaticStudyAnalysis, readAutomaticStudyAnalysisPrepared, requestAutomaticStudyAnalysisCancellationPrepared, } from "./job.js";
8
+ import { claimAutomaticAnalysis, readAutomaticAnalysisPrepared, requestAutomaticAnalysisCancellationPrepared, } from "./job.js";
9
9
  import { ANALYSIS_ID_PATTERN } from "./types.js";
10
- import { readStudyAnalysisVersion } from "./store.js";
11
- import { readStudyAnalysisExecution } from "./store-executions.js";
10
+ import { readAnalysisVersion } from "./store.js";
11
+ import { readAnalysisExecution } from "./store-executions.js";
12
12
  import { physicalCwdOf, resolvePhysicalCwd } from "../run/paths.js";
13
13
  const CANCELLATION_POLL_MS = 250;
14
14
  // Well inside AUTOMATIC_ANALYSIS_STALE_MS, so a live owner never reads as stale.
@@ -26,18 +26,18 @@ function hasParticipantEvidence(bundle) {
26
26
  });
27
27
  }
28
28
  /** Small read-only TUI/CLI projection. Neither this nor Observer can resume a job. */
29
- export async function readAutomaticStudyAnalysis(cwd, runId) {
29
+ export async function readAutomaticAnalysis(cwd, runId) {
30
30
  if (!exactId(runId))
31
31
  return undefined;
32
32
  const prepared = await resolveRunPath(await resolvePhysicalCwd(cwd), runId).catch(() => null);
33
- return prepared ? readAutomaticStudyAnalysisPrepared(prepared) : undefined;
33
+ return prepared ? readAutomaticAnalysisPrepared(prepared) : undefined;
34
34
  }
35
- export async function requestAutomaticStudyAnalysisCancellation(cwd, runId) {
35
+ export async function requestAutomaticAnalysisCancellation(cwd, runId) {
36
36
  if (!exactId(runId))
37
37
  return { requested: false, reason: "AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE" };
38
38
  const prepared = await resolveRunPath(await resolvePhysicalCwd(cwd), runId).catch(() => null);
39
39
  return prepared
40
- ? requestAutomaticStudyAnalysisCancellationPrepared(prepared)
40
+ ? requestAutomaticAnalysisCancellationPrepared(prepared)
41
41
  : { requested: false, reason: "AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE" };
42
42
  }
43
43
  /** The job reason for an analysis that reached a status. */
@@ -114,8 +114,8 @@ async function persistOutcome(job, prepared, outcome) {
114
114
  const analysisId = outcome.result?.analysisId;
115
115
  const [entry, receipt] = analysisId
116
116
  ? await Promise.all([
117
- readStudyAnalysisVersion(prepared, analysisId),
118
- readStudyAnalysisExecution(prepared, analysisId),
117
+ readAnalysisVersion(prepared, analysisId),
118
+ readAnalysisExecution(prepared, analysisId),
119
119
  ])
120
120
  : [null, null];
121
121
  await job.update({
@@ -131,7 +131,7 @@ async function persistOutcome(job, prepared, outcome) {
131
131
  }),
132
132
  ...(entry?.analysis ? { analysisSha256: hashAnalysisValue(entry.analysis) } : {}),
133
133
  });
134
- const persisted = await readAutomaticStudyAnalysisPrepared(prepared);
134
+ const persisted = await readAutomaticAnalysisPrepared(prepared);
135
135
  return persisted?.state === "unknown"
136
136
  ? { ...outcome, state: "unknown", reason: persisted.reason }
137
137
  : outcome;
@@ -143,7 +143,7 @@ async function persistOutcome(job, prepared, outcome) {
143
143
  /** One permanent claim per completed run, consumed even when preparation/cancellation fails.
144
144
  * Only the original producer calls this after all recording writes return.
145
145
  * No file reader, restart recovery, Observer poll or export calls this function. */
146
- export async function runAutomaticStudyAnalysis(cwdInput, runId, configInput, deps = {}) {
146
+ export async function runAutomaticAnalysis(cwdInput, runId, configInput, deps = {}) {
147
147
  if (!exactId(runId))
148
148
  return skipped("AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE");
149
149
  let cwd = path.resolve(cwdInput);
@@ -162,7 +162,7 @@ export async function runAutomaticStudyAnalysis(cwdInput, runId, configInput, de
162
162
  config = await (await import("./restricted-codex.js")).bindCodexAnalysisCliVersion(config, deps.detectCodexCliVersion);
163
163
  let job;
164
164
  try {
165
- const claimed = await claimAutomaticStudyAnalysis(prepared, {
165
+ const claimed = await claimAutomaticAnalysis(prepared, {
166
166
  configDigest: hashAnalysisValue(config),
167
167
  promptVersion: ANALYSIS_PROMPT_VERSION,
168
168
  });
@@ -211,7 +211,11 @@ export async function runAutomaticStudyAnalysis(cwdInput, runId, configInput, de
211
211
  try {
212
212
  await poll();
213
213
  const missingKey = config.provider !== "codex" && !hasKey;
214
- if (deps.defaultRequest === true && (missingKey || !participantEvidence)) {
214
+ const refused = deps.refusal?.();
215
+ if (refused !== undefined) {
216
+ outcome = skipped(refused);
217
+ }
218
+ else if (deps.defaultRequest === true && (missingKey || !participantEvidence)) {
215
219
  outcome = signal.aborted
216
220
  ? { state: "cancelled", reason: "AUTOMATIC_ANALYSIS_CANCELLED" }
217
221
  : skipped(missingKey
@@ -2,7 +2,11 @@ import type { CodexAnalysisIdentity, AnalysisConfig } from "./types.js";
2
2
  export declare const CODEX_ANALYSIS_MODEL: "gpt-6-astra";
3
3
  /** Before dispatch, analysis replaces the default release with the detected one. */
4
4
  export declare function codexAnalysisIdentity(model: string, cliVersion?: string): CodexAnalysisIdentity;
5
- /** Execution admission: the identity must name a release qualified on this host. */
5
+ /** Execution admission: an isolated-mode host, and an identity naming a release the launcher starts. */
6
6
  export declare function validCodexAnalysisConfig(config: AnalysisConfig, platform?: NodeJS.Platform, arch?: string): boolean;
7
- /** Reading historical artifacts never inserts defaults or selects a launch policy. */
7
+ /**
8
+ * Reading historical artifacts never inserts defaults or selects a launch policy: the restricted
9
+ * analyst's fixed identity, from any recordable release, so a change to launch admission never
10
+ * invalidates a saved report.
11
+ */
8
12
  export declare function validStoredCodexAnalysisConfig(config: AnalysisConfig): boolean;
@@ -1,7 +1,7 @@
1
- import { RECORDED_CODEX_CLI_VERSIONS } from "../actors/contract.js";
2
- import { defaultCodexCliVersion, qualifiedCodexCliVersions, } from "../actors/codex/qualified-versions.js";
1
+ import { isRecordedCodexCliVersion } from "../actors/contract.js";
2
+ import { admitsCodexCliVersion, defaultCodexCliVersion, supportsIsolatedCodex, } from "../actors/codex/codex-admission.js";
3
3
  import { RESTRICTED_CODEX_ANALYSIS_IDENTITY, RESTRICTED_CODEX_ANALYSIS_MODELS, } from "../actors/codex/restricted-policy.js";
4
- /** This account route is qualified against per-host CLI releases, one model and one tool policy. */
4
+ /** This account route runs the releases codex-admission.ts admits, one model and one tool policy. */
5
5
  const CODEX_ANALYSIS_TOOL_POLICY = RESTRICTED_CODEX_ANALYSIS_IDENTITY.toolPolicy;
6
6
  export const CODEX_ANALYSIS_MODEL = RESTRICTED_CODEX_ANALYSIS_MODELS[0];
7
7
  const CODEX_ANALYSIS_EFFORT = RESTRICTED_CODEX_ANALYSIS_IDENTITY.reasoningEffort;
@@ -26,13 +26,6 @@ export function codexAnalysisIdentity(model, cliVersion = defaultCodexCliVersion
26
26
  cliVersion,
27
27
  });
28
28
  }
29
- /** Reader profiles are append-only. A new launch qualification must not invalidate a saved report. */
30
- const storedProfiles = RECORDED_CODEX_CLI_VERSIONS.map((cliVersion) => ({
31
- cliVersion,
32
- toolPolicy: "restricted-codex-v1",
33
- model: "gpt-6-astra",
34
- reasoningEffort: "low",
35
- }));
36
29
  function matchesProfile(config, expected) {
37
30
  if (config.provider !== "codex")
38
31
  return false;
@@ -54,16 +47,31 @@ function matchesProfile(config, expected) {
54
47
  Object.keys(config.identity).length === Object.keys(expected).length &&
55
48
  Object.entries(expected).every(([key, value]) => config.identity[key] === value));
56
49
  }
57
- /** Execution admission: the identity must name a release qualified on this host. */
50
+ /** Execution admission: an isolated-mode host, and an identity naming a release the launcher starts. */
58
51
  export function validCodexAnalysisConfig(config, platform = process.platform, arch = process.arch) {
59
52
  if (config.provider !== "codex")
60
53
  return false;
61
54
  const cliVersion = config.identity?.cliVersion;
62
55
  return (config.model === CODEX_ANALYSIS_MODEL &&
63
- qualifiedCodexCliVersions(platform, arch).some((version) => version === cliVersion) &&
56
+ supportsIsolatedCodex(platform, arch) &&
57
+ typeof cliVersion === "string" &&
58
+ admitsCodexCliVersion(cliVersion) &&
64
59
  matchesProfile(config, codexAnalysisIdentity(config.model, cliVersion)));
65
60
  }
66
- /** Reading historical artifacts never inserts defaults or selects a launch policy. */
61
+ /**
62
+ * Reading historical artifacts never inserts defaults or selects a launch policy: the restricted
63
+ * analyst's fixed identity, from any recordable release, so a change to launch admission never
64
+ * invalidates a saved report.
65
+ */
67
66
  export function validStoredCodexAnalysisConfig(config) {
68
- return storedProfiles.some((profile) => matchesProfile(config, identityFor(profile)));
67
+ if (config.provider !== "codex")
68
+ return false;
69
+ const cliVersion = config.identity?.cliVersion;
70
+ return (isRecordedCodexCliVersion(cliVersion) &&
71
+ matchesProfile(config, identityFor({
72
+ cliVersion,
73
+ toolPolicy: "restricted-codex-v1",
74
+ model: "gpt-6-astra",
75
+ reasoningEffort: "low",
76
+ })));
69
77
  }
@@ -0,0 +1,23 @@
1
+ /** How many rejected outputs are kept across all runs; older ones are removed on each write. */
2
+ export declare const MAX_ANALYSIS_DIAGNOSTICS = 20;
3
+ export interface RejectedAnalysisOutput {
4
+ /** The allowlisted code the analysis artifact records. */
5
+ error: string;
6
+ /** Every failed validation rule, when validation ran. */
7
+ errors: string[];
8
+ /** The response after the narrative scrub when validation ran, else the parsed response. */
9
+ output: unknown;
10
+ }
11
+ export interface RejectedAnalysisRecord {
12
+ runId: string;
13
+ analysisId: string;
14
+ model: string;
15
+ promptVersion: string;
16
+ }
17
+ /** Internal fault-injection seam for tests. */
18
+ export interface AnalysisDiagnosticsHooks {
19
+ /** Runs after pruning has listed the records and before it removes any. */
20
+ beforeRemove?: () => Promise<void>;
21
+ }
22
+ /** Write one rejected output and prune to the newest MAX_ANALYSIS_DIAGNOSTICS. Returns its path relative to cwd. */
23
+ export declare function keepRejectedAnalysisOutput(cwd: string, record: RejectedAnalysisRecord, rejected: RejectedAnalysisOutput, hooks?: AnalysisDiagnosticsHooks): Promise<string>;