humanish 0.107.0 → 0.108.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (521) hide show
  1. package/ARCHITECTURE.md +22 -17
  2. package/CHANGELOG.md +14 -0
  3. package/CONTEXT.md +51 -44
  4. package/README.md +145 -172
  5. package/SECURITY.md +16 -26
  6. package/TELEMETRY.md +8 -6
  7. package/dist/actors/affordance.d.ts +4 -4
  8. package/dist/actors/affordance.js +12 -12
  9. package/dist/actors/agent-session.d.ts +2 -2
  10. package/dist/actors/agent-session.js +7 -7
  11. package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
  12. package/dist/actors/codex/app-server-actor-trace.js +1 -1
  13. package/dist/actors/codex/app-server-ui.js +1 -1
  14. package/dist/actors/codex/codex-admission.d.ts +91 -0
  15. package/dist/actors/codex/codex-admission.js +150 -0
  16. package/dist/actors/codex/restricted-executable.d.ts +4 -4
  17. package/dist/actors/codex/restricted-executable.js +8 -8
  18. package/dist/actors/codex/restricted-launch.d.ts +2 -1
  19. package/dist/actors/codex/restricted-launch.js +1 -1
  20. package/dist/actors/codex/restricted-participant.js +8 -6
  21. package/dist/actors/codex/restricted-policy.d.ts +2 -2
  22. package/dist/actors/codex/restricted-policy.js +2 -2
  23. package/dist/actors/codex/restricted-session.d.ts +2 -2
  24. package/dist/actors/codex/restricted-session.js +10 -5
  25. package/dist/actors/computer-use/actor.d.ts +16 -16
  26. package/dist/actors/computer-use/actor.js +2 -2
  27. package/dist/actors/computer-use/admission-limit.d.ts +1 -1
  28. package/dist/actors/computer-use/admission-limit.js +1 -1
  29. package/dist/actors/computer-use/loop/actions.d.ts +3 -3
  30. package/dist/actors/computer-use/loop/actions.js +10 -10
  31. package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
  32. package/dist/actors/computer-use/loop/backstop.js +14 -12
  33. package/dist/actors/computer-use/loop/ending.d.ts +5 -5
  34. package/dist/actors/computer-use/loop/ending.js +7 -7
  35. package/dist/actors/computer-use/loop/observation.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/observation.js +9 -9
  37. package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/provider-call.js +1 -1
  39. package/dist/actors/computer-use/loop/session.js +3 -3
  40. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  41. package/dist/actors/computer-use/loop/spend.js +1 -1
  42. package/dist/actors/computer-use/loop/trace.js +9 -8
  43. package/dist/actors/computer-use/loop/types.d.ts +25 -23
  44. package/dist/actors/computer-use/loop/usage.js +2 -2
  45. package/dist/actors/computer-use/openai-context.d.ts +37 -0
  46. package/dist/actors/computer-use/openai-context.js +214 -0
  47. package/dist/actors/computer-use/openai-provider.d.ts +11 -8
  48. package/dist/actors/computer-use/openai-provider.js +45 -34
  49. package/dist/actors/computer-use/openai-requests.d.ts +36 -10
  50. package/dist/actors/computer-use/openai-requests.js +82 -15
  51. package/dist/actors/computer-use/openai-wire.d.ts +19 -7
  52. package/dist/actors/computer-use/openai-wire.js +36 -34
  53. package/dist/actors/contract.d.ts +78 -43
  54. package/dist/actors/contract.js +29 -23
  55. package/dist/actors/local-agent/claude-session.d.ts +1 -1
  56. package/dist/actors/local-agent/claude-session.js +10 -9
  57. package/dist/actors/local-agent/cli.d.ts +8 -6
  58. package/dist/actors/local-agent/cli.js +24 -28
  59. package/dist/actors/local-agent/readiness.d.ts +2 -2
  60. package/dist/actors/local-agent/readiness.js +4 -4
  61. package/dist/actors/reasoning-effort.js +6 -6
  62. package/dist/actors/registry.d.ts +10 -10
  63. package/dist/actors/registry.js +18 -17
  64. package/dist/actors/scripted-browser/actor.d.ts +8 -8
  65. package/dist/actors/scripted-browser/actor.js +16 -16
  66. package/dist/actors/scripted-browser/browser-command.js +1 -1
  67. package/dist/actors/scripted-browser/steps.js +1 -1
  68. package/dist/actors/scripted-browser/types.d.ts +1 -1
  69. package/dist/actors/stop-conditions.d.ts +1 -1
  70. package/dist/analysis/codex-config.d.ts +6 -2
  71. package/dist/analysis/codex-config.js +22 -14
  72. package/dist/analysis/service.js +5 -5
  73. package/dist/cli/commands/analyze.js +19 -16
  74. package/dist/cli/commands/codex.js +9 -9
  75. package/dist/cli/commands/comms.js +54 -33
  76. package/dist/cli/commands/feedback.js +20 -21
  77. package/dist/cli/commands/lab-format.d.ts +5 -4
  78. package/dist/cli/commands/lab-format.js +35 -23
  79. package/dist/cli/commands/lab-route-computer-use.js +6 -7
  80. package/dist/cli/commands/lab-route-preview.js +4 -3
  81. package/dist/cli/commands/lab-route-shared-world.js +3 -3
  82. package/dist/cli/commands/lab-run.js +10 -11
  83. package/dist/cli/commands/lab-scorer.d.ts +2 -2
  84. package/dist/cli/commands/lab-scorer.js +1 -1
  85. package/dist/cli/commands/migrate.d.ts +4 -0
  86. package/dist/cli/commands/migrate.js +65 -0
  87. package/dist/cli/commands/observe.js +147 -108
  88. package/dist/cli/commands/run-command.d.ts +10 -0
  89. package/dist/cli/commands/run-command.js +85 -0
  90. package/dist/cli/commands/runs.js +137 -138
  91. package/dist/cli/commands/setup.d.ts +2 -2
  92. package/dist/cli/commands/setup.js +26 -21
  93. package/dist/cli/commands/study.d.ts +3 -0
  94. package/dist/cli/commands/study.js +182 -0
  95. package/dist/cli/commands/tui.d.ts +4 -4
  96. package/dist/cli/commands/tui.js +21 -21
  97. package/dist/cli/commands/watch.js +60 -75
  98. package/dist/cli/deprecations.d.ts +18 -0
  99. package/dist/cli/deprecations.js +48 -0
  100. package/dist/cli/doctor.d.ts +15 -5
  101. package/dist/cli/doctor.js +103 -48
  102. package/dist/cli/first-run-path.d.ts +12 -10
  103. package/dist/cli/first-run-path.js +30 -28
  104. package/dist/cli/io.d.ts +41 -6
  105. package/dist/cli/io.js +97 -22
  106. package/dist/cli/observer-follow.d.ts +2 -2
  107. package/dist/cli/observer-follow.js +5 -6
  108. package/dist/cli/orientation.d.ts +6 -3
  109. package/dist/cli/orientation.js +43 -39
  110. package/dist/cli/product-sentence.d.ts +6 -0
  111. package/dist/cli/product-sentence.js +6 -0
  112. package/dist/cli/program.d.ts +6 -1
  113. package/dist/cli/program.js +109 -40
  114. package/dist/cli/telemetry.d.ts +15 -15
  115. package/dist/cli/telemetry.js +48 -40
  116. package/dist/cli.js +1 -1
  117. package/dist/comms/capture-surface.d.ts +13 -12
  118. package/dist/comms/capture-surface.js +23 -22
  119. package/dist/comms/catch-host.d.ts +7 -7
  120. package/dist/comms/catch-host.js +14 -14
  121. package/dist/comms/email-catch.d.ts +3 -3
  122. package/dist/comms/email-catch.js +8 -8
  123. package/dist/comms/external-evidence.js +2 -2
  124. package/dist/comms/extract.js +2 -2
  125. package/dist/comms/fake-inbox.d.ts +2 -2
  126. package/dist/comms/fake-inbox.js +2 -2
  127. package/dist/comms/receiving-render.d.ts +1 -1
  128. package/dist/comms/receiving-render.js +2 -2
  129. package/dist/comms/sandbox-catch-script.d.ts +6 -6
  130. package/dist/comms/sandbox-catch-script.js +6 -6
  131. package/dist/comms/sandbox-catch.d.ts +36 -37
  132. package/dist/comms/sandbox-catch.js +34 -35
  133. package/dist/comms/setup.js +42 -8
  134. package/dist/comms/thread-evidence.d.ts +1 -1
  135. package/dist/comms/thread-evidence.js +6 -6
  136. package/dist/comms/types.d.ts +6 -6
  137. package/dist/comms/types.js +3 -3
  138. package/dist/evidence/frame-signature.d.ts +1 -1
  139. package/dist/evidence/frame-signature.js +4 -4
  140. package/dist/evidence/redaction.d.ts +3 -3
  141. package/dist/evidence/redaction.js +4 -4
  142. package/dist/feedback/draft.js +36 -78
  143. package/dist/feedback/export-bundle.js +1 -1
  144. package/dist/feedback/export.d.ts +5 -1
  145. package/dist/feedback/export.js +7 -8
  146. package/dist/feedback/feedback.d.ts +2 -2
  147. package/dist/feedback/feedback.js +21 -3
  148. package/dist/guest/chromium-text.js +2 -2
  149. package/dist/guest/desktop-native.d.ts +1 -1
  150. package/dist/guest/runtime.js +1 -1
  151. package/dist/index.d.ts +12 -10
  152. package/dist/index.js +8 -6
  153. package/dist/keys/key-resolution.d.ts +5 -5
  154. package/dist/keys/key-resolution.js +23 -23
  155. package/dist/lab/adapter-extension.d.ts +7 -7
  156. package/dist/lab/adapter-extension.js +13 -36
  157. package/dist/lab/adapter-scorer-loader.d.ts +7 -7
  158. package/dist/lab/adapter-scorer-loader.js +32 -32
  159. package/dist/lab/composition-rules.js +42 -42
  160. package/dist/lab/config.js +65 -25
  161. package/dist/lab/deprecated-fields.d.ts +10 -0
  162. package/dist/lab/deprecated-fields.js +24 -0
  163. package/dist/lab/device-presets.d.ts +8 -8
  164. package/dist/lab/device-presets.js +11 -11
  165. package/dist/lab/discover.d.ts +13 -9
  166. package/dist/lab/discover.js +117 -57
  167. package/dist/lab/doctor.d.ts +10 -3
  168. package/dist/lab/doctor.js +47 -9
  169. package/dist/lab/init-templates.js +147 -147
  170. package/dist/lab/init.d.ts +1 -1
  171. package/dist/lab/init.js +41 -9
  172. package/dist/lab/keys.d.ts +2 -0
  173. package/dist/lab/keys.js +42 -8
  174. package/dist/lab/lab-deps.d.ts +7 -12
  175. package/dist/lab/parse/actors.js +9 -9
  176. package/dist/lab/parse/comms.js +5 -5
  177. package/dist/lab/parse/execution.js +13 -13
  178. package/dist/lab/parse/study-v3.d.ts +23 -0
  179. package/dist/lab/parse/study-v3.js +259 -0
  180. package/dist/lab/parse/subject-state.d.ts +7 -7
  181. package/dist/lab/parse/subject-state.js +16 -16
  182. package/dist/lab/parse/subject.js +28 -28
  183. package/dist/lab/parse/values.d.ts +1 -1
  184. package/dist/lab/parse/values.js +3 -3
  185. package/dist/lab/persona-resolve.d.ts +4 -4
  186. package/dist/lab/persona-resolve.js +4 -4
  187. package/dist/lab/plan-participants.d.ts +2 -2
  188. package/dist/lab/plan-types.d.ts +4 -4
  189. package/dist/lab/plan.d.ts +1 -7
  190. package/dist/lab/plan.js +10 -41
  191. package/dist/lab/preflight-probes.js +11 -11
  192. package/dist/lab/preflight-result.d.ts +2 -1
  193. package/dist/lab/preflight-result.js +5 -4
  194. package/dist/lab/preflight.d.ts +7 -5
  195. package/dist/lab/preflight.js +5 -5
  196. package/dist/lab/routing.d.ts +31 -25
  197. package/dist/lab/routing.js +60 -29
  198. package/dist/lab/run-lab-events.d.ts +0 -3
  199. package/dist/lab/run-lab-events.js +0 -6
  200. package/dist/lab/run-lab-homes.d.ts +22 -10
  201. package/dist/lab/run-lab-homes.js +5 -1
  202. package/dist/lab/run-lab-options.d.ts +1 -1
  203. package/dist/lab/run-lab-options.js +16 -13
  204. package/dist/lab/summary.d.ts +7 -6
  205. package/dist/lab/summary.js +10 -10
  206. package/dist/lab/tasks.d.ts +15 -15
  207. package/dist/lab/tasks.js +14 -14
  208. package/dist/lab/types.d.ts +101 -95
  209. package/dist/lab/types.js +2 -0
  210. package/dist/lab/validation.d.ts +13 -13
  211. package/dist/lab/validation.js +44 -42
  212. package/dist/lab/warnings.d.ts +10 -0
  213. package/dist/lab/warnings.js +61 -33
  214. package/dist/library-aliases.d.ts +56 -0
  215. package/dist/library-aliases.js +22 -0
  216. package/dist/observer/artifact.d.ts +1 -1
  217. package/dist/observer/artifact.js +6 -6
  218. package/dist/observer/data.d.ts +6 -6
  219. package/dist/observer/data.js +5 -4
  220. package/dist/observer/exposure.d.ts +1 -1
  221. package/dist/observer/exposure.js +11 -11
  222. package/dist/observer/http.js +1 -1
  223. package/dist/observer/library.d.ts +1 -1
  224. package/dist/observer/library.js +4 -2
  225. package/dist/observer/listen.js +5 -4
  226. package/dist/observer/render.d.ts +1 -1
  227. package/dist/observer/render.js +10 -5
  228. package/dist/observer/run-routes.d.ts +3 -3
  229. package/dist/observer/run-routes.js +1 -1
  230. package/dist/observer/serve.js +7 -3
  231. package/dist/observer/tunnel.js +1 -1
  232. package/dist/observer-app.html +4 -4
  233. package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
  234. package/dist/routes/computer-use/bundle-parts.js +15 -15
  235. package/dist/routes/computer-use/bundle.js +3 -3
  236. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
  237. package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
  238. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
  239. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
  240. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
  241. package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
  242. package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
  243. package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
  244. package/dist/routes/computer-use/external-comms.d.ts +1 -1
  245. package/dist/routes/computer-use/external-comms.js +1 -1
  246. package/dist/routes/computer-use/fanout-bundle.js +18 -18
  247. package/dist/routes/computer-use/fanout-records.js +10 -11
  248. package/dist/routes/computer-use/live-flush.d.ts +1 -1
  249. package/dist/routes/computer-use/live-flush.js +6 -6
  250. package/dist/routes/computer-use/live-phase.d.ts +4 -2
  251. package/dist/routes/computer-use/live-phase.js +6 -6
  252. package/dist/routes/computer-use/local-vm.js +1 -1
  253. package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
  254. package/dist/routes/computer-use/participant-desktop.js +4 -4
  255. package/dist/routes/computer-use/participant-execution.d.ts +4 -4
  256. package/dist/routes/computer-use/participant-execution.js +9 -9
  257. package/dist/routes/computer-use/participant-model.d.ts +6 -0
  258. package/dist/routes/computer-use/participant-model.js +31 -13
  259. package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
  260. package/dist/routes/computer-use/participant-prompt.js +6 -6
  261. package/dist/routes/computer-use/participant-runs.d.ts +7 -7
  262. package/dist/routes/computer-use/participant-runs.js +13 -13
  263. package/dist/routes/computer-use/plan.js +22 -22
  264. package/dist/routes/computer-use/preflight.js +21 -21
  265. package/dist/routes/computer-use/rerun-selection.js +1 -1
  266. package/dist/routes/computer-use/result.js +11 -11
  267. package/dist/routes/computer-use/route.d.ts +2 -1
  268. package/dist/routes/computer-use/route.js +15 -14
  269. package/dist/routes/computer-use/self-report.d.ts +7 -7
  270. package/dist/routes/computer-use/self-report.js +31 -31
  271. package/dist/routes/computer-use/setup.d.ts +1 -1
  272. package/dist/routes/computer-use/setup.js +17 -18
  273. package/dist/routes/computer-use/single-bundle.d.ts +7 -7
  274. package/dist/routes/computer-use/single-bundle.js +28 -30
  275. package/dist/routes/computer-use/subject-projection.d.ts +1 -1
  276. package/dist/routes/computer-use/subject-projection.js +6 -6
  277. package/dist/routes/computer-use/types.d.ts +40 -42
  278. package/dist/routes/computer-use/types.js +10 -10
  279. package/dist/routes/preview.d.ts +8 -2
  280. package/dist/routes/preview.js +8 -4
  281. package/dist/routes/scripted/bundle.d.ts +2 -2
  282. package/dist/routes/scripted/bundle.js +13 -12
  283. package/dist/routes/scripted/plan.d.ts +1 -1
  284. package/dist/routes/scripted/plan.js +9 -9
  285. package/dist/routes/scripted/result.js +5 -5
  286. package/dist/routes/scripted/route.js +5 -6
  287. package/dist/routes/scripted/scenario.js +2 -2
  288. package/dist/routes/scripted/setup.js +7 -7
  289. package/dist/routes/scripted/subject.js +1 -1
  290. package/dist/routes/scripted/surface-records.js +3 -3
  291. package/dist/routes/scripted/types.d.ts +3 -5
  292. package/dist/routes/scripted/types.js +1 -1
  293. package/dist/routes/shared-world/bundle-records.js +9 -8
  294. package/dist/routes/shared-world/bundle.d.ts +5 -5
  295. package/dist/routes/shared-world/bundle.js +40 -38
  296. package/dist/routes/shared-world/checkpoints.d.ts +1 -1
  297. package/dist/routes/shared-world/checkpoints.js +1 -1
  298. package/dist/routes/shared-world/comms.d.ts +5 -5
  299. package/dist/routes/shared-world/comms.js +14 -14
  300. package/dist/routes/shared-world/external-public.d.ts +4 -3
  301. package/dist/routes/shared-world/external-public.js +16 -12
  302. package/dist/routes/shared-world/handoff.d.ts +7 -6
  303. package/dist/routes/shared-world/handoff.js +65 -57
  304. package/dist/routes/shared-world/lobby-code.d.ts +2 -2
  305. package/dist/routes/shared-world/lobby-code.js +9 -9
  306. package/dist/routes/shared-world/participant-specs.d.ts +7 -6
  307. package/dist/routes/shared-world/participant-specs.js +31 -24
  308. package/dist/routes/shared-world/plan.js +7 -7
  309. package/dist/routes/shared-world/provenance.d.ts +2 -2
  310. package/dist/routes/shared-world/provenance.js +2 -2
  311. package/dist/routes/shared-world/provisioned.js +14 -13
  312. package/dist/routes/shared-world/result.js +20 -21
  313. package/dist/routes/shared-world/route.js +23 -22
  314. package/dist/routes/shared-world/setup.d.ts +3 -3
  315. package/dist/routes/shared-world/setup.js +4 -4
  316. package/dist/routes/shared-world/types.d.ts +30 -28
  317. package/dist/routes/shared-world/types.js +4 -4
  318. package/dist/routes/terminal/adapter.d.ts +3 -3
  319. package/dist/routes/terminal/adapter.js +5 -5
  320. package/dist/routes/terminal/bundle.d.ts +3 -3
  321. package/dist/routes/terminal/bundle.js +22 -21
  322. package/dist/routes/terminal/credentials.d.ts +4 -4
  323. package/dist/routes/terminal/credentials.js +7 -7
  324. package/dist/routes/terminal/dry-run.js +4 -4
  325. package/dist/routes/terminal/encoding.js +2 -2
  326. package/dist/routes/terminal/ledger.d.ts +3 -3
  327. package/dist/routes/terminal/ledger.js +14 -14
  328. package/dist/routes/terminal/live-finish.js +3 -3
  329. package/dist/routes/terminal/live-sandbox.js +12 -13
  330. package/dist/routes/terminal/persona.js +1 -1
  331. package/dist/routes/terminal/plan.js +11 -11
  332. package/dist/routes/terminal/recorder.js +2 -2
  333. package/dist/routes/terminal/result.js +8 -8
  334. package/dist/routes/terminal/route.js +6 -7
  335. package/dist/routes/terminal/sandbox.d.ts +1 -1
  336. package/dist/routes/terminal/sandbox.js +1 -1
  337. package/dist/routes/terminal/session.js +8 -7
  338. package/dist/routes/terminal/token-usage.d.ts +1 -1
  339. package/dist/routes/terminal/token-usage.js +7 -8
  340. package/dist/routes/terminal/trace.d.ts +2 -2
  341. package/dist/routes/terminal/trace.js +2 -2
  342. package/dist/routes/terminal/types.d.ts +26 -28
  343. package/dist/routes/terminal/types.js +3 -3
  344. package/dist/run/bundle-shape.js +3 -3
  345. package/dist/run/bundle.d.ts +46 -46
  346. package/dist/run/bundle.js +2 -1
  347. package/dist/run/cost-summary.js +3 -3
  348. package/dist/run/costs.js +7 -1
  349. package/dist/run/detail.d.ts +6 -6
  350. package/dist/run/detail.js +4 -4
  351. package/dist/run/dry-run-inputs.js +1 -1
  352. package/dist/run/dry-run.js +18 -18
  353. package/dist/run/judge.d.ts +19 -13
  354. package/dist/run/judge.js +18 -8
  355. package/dist/run/paths.d.ts +1 -1
  356. package/dist/run/paths.js +1 -1
  357. package/dist/run/pricing.d.ts +11 -6
  358. package/dist/run/pricing.js +20 -13
  359. package/dist/run/projection.d.ts +14 -14
  360. package/dist/run/projection.js +15 -15
  361. package/dist/run/reclaim.js +2 -2
  362. package/dist/run/results.d.ts +5 -5
  363. package/dist/run/run-index.d.ts +8 -6
  364. package/dist/run/run-index.js +15 -16
  365. package/dist/run/run-not-found.d.ts +5 -0
  366. package/dist/run/run-not-found.js +15 -0
  367. package/dist/run/run.d.ts +5 -4
  368. package/dist/run/run.js +1 -1
  369. package/dist/run/sandbox-receipts.d.ts +2 -2
  370. package/dist/run/sandbox-receipts.js +3 -3
  371. package/dist/run/shared-world-evidence.d.ts +36 -35
  372. package/dist/run/shared-world-evidence.js +4 -4
  373. package/dist/run/shared-world-shape.d.ts +1 -1
  374. package/dist/run/shared-world-shape.js +6 -6
  375. package/dist/run/stats.d.ts +12 -6
  376. package/dist/run/stats.js +116 -58
  377. package/dist/run/status.d.ts +8 -29
  378. package/dist/run/status.js +5 -27
  379. package/dist/run/stored-runs.js +2 -1
  380. package/dist/run/stream-shape.js +1 -1
  381. package/dist/run/streams.d.ts +6 -6
  382. package/dist/run/study-provenance.d.ts +47 -0
  383. package/dist/run/study-provenance.js +63 -0
  384. package/dist/run/study-result.d.ts +16 -0
  385. package/dist/run/study-result.js +9 -0
  386. package/dist/run/text.d.ts +2 -0
  387. package/dist/run/text.js +4 -0
  388. package/dist/run-lab.d.ts +7 -7
  389. package/dist/run-lab.js +1 -3
  390. package/dist/study/convert.d.ts +33 -0
  391. package/dist/study/convert.js +432 -0
  392. package/dist/study/field-paths.d.ts +12 -0
  393. package/dist/study/field-paths.js +126 -0
  394. package/dist/study/files.d.ts +26 -0
  395. package/dist/study/files.js +43 -0
  396. package/dist/study/migrate.d.ts +48 -0
  397. package/dist/study/migrate.js +408 -0
  398. package/dist/study/owned-files.d.ts +38 -0
  399. package/dist/study/owned-files.js +182 -0
  400. package/dist/subject/clone.d.ts +1 -1
  401. package/dist/subject/desktop-cli.d.ts +1 -1
  402. package/dist/subject/desktop-cli.js +2 -2
  403. package/dist/subject/local-tree-archive.js +1 -1
  404. package/dist/subject/local-tree.d.ts +1 -1
  405. package/dist/subject/node-bootstrap.js +1 -1
  406. package/dist/subject/runtime.js +8 -9
  407. package/dist/subject/serve.d.ts +1 -1
  408. package/dist/subject/serve.js +3 -3
  409. package/dist/subject/state.d.ts +1 -1
  410. package/dist/subject/steps.d.ts +5 -5
  411. package/dist/subject/steps.js +4 -4
  412. package/dist/substrates/command-failure.d.ts +3 -3
  413. package/dist/substrates/command-failure.js +3 -3
  414. package/dist/substrates/detached.d.ts +6 -6
  415. package/dist/substrates/detached.js +7 -7
  416. package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
  417. package/dist/substrates/e2b/cdp-probe.js +14 -17
  418. package/dist/substrates/e2b/desktop-browser.d.ts +2 -2
  419. package/dist/substrates/e2b/desktop-browser.js +8 -8
  420. package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
  421. package/dist/substrates/e2b/desktop-cdp.js +8 -8
  422. package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
  423. package/dist/substrates/e2b/desktop-executor.js +1 -1
  424. package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
  425. package/dist/substrates/e2b/desktop-geometry.js +7 -7
  426. package/dist/substrates/e2b/desktop-media.d.ts +1 -1
  427. package/dist/substrates/e2b/desktop-media.js +1 -1
  428. package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
  429. package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
  430. package/dist/substrates/e2b/sandbox.d.ts +1 -1
  431. package/dist/substrates/e2b/sandbox.js +1 -1
  432. package/dist/substrates/e2b/sdk.d.ts +11 -11
  433. package/dist/substrates/e2b/sdk.js +6 -6
  434. package/dist/tui/actions.d.ts +1 -1
  435. package/dist/tui/actions.js +13 -13
  436. package/dist/tui/contract.d.ts +16 -16
  437. package/dist/tui/contract.js +10 -10
  438. package/dist/tui/launch.d.ts +4 -4
  439. package/dist/tui/launch.js +18 -19
  440. package/dist/tui/project.js +5 -5
  441. package/dist/tui-app.js +82 -82
  442. package/dist/verify/actor.d.ts +8 -8
  443. package/dist/verify/actor.js +36 -36
  444. package/dist/verify/artifacts.d.ts +2 -2
  445. package/dist/verify/artifacts.js +3 -3
  446. package/dist/verify/context-growth.d.ts +9 -0
  447. package/dist/verify/context-growth.js +62 -0
  448. package/dist/verify/costs.d.ts +6 -6
  449. package/dist/verify/costs.js +8 -8
  450. package/dist/verify/shared-world-concurrent.d.ts +2 -2
  451. package/dist/verify/shared-world-concurrent.js +79 -76
  452. package/dist/verify/shared-world.d.ts +2 -2
  453. package/dist/verify/shared-world.js +16 -16
  454. package/dist/verify/subject.d.ts +4 -4
  455. package/dist/verify/subject.js +18 -18
  456. package/dist/verify/verify.js +92 -43
  457. package/docs/README.md +25 -32
  458. package/docs/architecture/actor-contract.md +56 -87
  459. package/docs/architecture/desktop-sessions.md +7 -7
  460. package/docs/architecture/external-public-shared-world.md +61 -59
  461. package/docs/architecture/github-feedback-loop.md +1 -4
  462. package/docs/architecture/guest-desktop.md +2 -2
  463. package/docs/architecture/observer.md +34 -34
  464. package/docs/architecture/restricted-codex-analysis.md +34 -28
  465. package/docs/architecture/serve.md +34 -37
  466. package/docs/architecture/state-driven-executor.md +55 -58
  467. package/docs/architecture/task-protocol-support.md +5 -5
  468. package/docs/architecture/terminal-product-route.md +67 -107
  469. package/docs/contracts/README.md +24 -0
  470. package/docs/contracts/adapter-admission.md +3 -3
  471. package/docs/contracts/adapter-fixtures.md +2 -5
  472. package/docs/contracts/core.md +1 -3
  473. package/docs/contracts/errors.md +62 -0
  474. package/docs/contracts/feedback.md +8 -9
  475. package/docs/contracts/policy.md +7 -12
  476. package/docs/contracts/run-bundle.md +45 -44
  477. package/docs/contracts/schemas.md +421 -362
  478. package/docs/contracts/study-analysis.md +3 -3
  479. package/docs/contracts/study-costs.md +11 -7
  480. package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
  481. package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
  482. package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
  483. package/docs/principles/actor-fidelity.md +4 -4
  484. package/docs/principles/engineering.md +3 -3
  485. package/docs/principles/invariants-and-defaults.md +38 -38
  486. package/docs/principles/self-driving-harness.md +1 -5
  487. package/docs/principles/three-roles.md +1 -1
  488. package/docs/product/automatic-analysis.md +7 -7
  489. package/examples/participant/README.md +5 -5
  490. package/examples/participant/run.mjs +11 -10
  491. package/examples/scorer/README.md +3 -3
  492. package/examples/scorer/run.mjs +11 -12
  493. package/package.json +16 -17
  494. package/skills/humanish/SKILL.md +60 -58
  495. package/skills/humanish/agents/openai.yaml +1 -1
  496. package/AGENTS.md +0 -99
  497. package/CONTRIBUTING.md +0 -148
  498. package/dist/actors/codex/qualified-versions.d.ts +0 -72
  499. package/dist/actors/codex/qualified-versions.js +0 -132
  500. package/dist/cli/commands/lab.d.ts +0 -3
  501. package/dist/cli/commands/lab.js +0 -199
  502. package/dist/cli/renamed-options.d.ts +0 -11
  503. package/dist/cli/renamed-options.js +0 -18
  504. package/dist/observer/static.d.ts +0 -39
  505. package/dist/observer/static.js +0 -369
  506. package/docs/architecture/comms-inbox.md +0 -122
  507. package/docs/architecture/desktop-recording.md +0 -80
  508. package/docs/architecture/local-browser-runtime.md +0 -178
  509. package/docs/architecture/observer-review.md +0 -144
  510. package/docs/architecture/participant-media.md +0 -90
  511. package/docs/architecture/project-layout.md +0 -62
  512. package/docs/architecture/real-email-receiving.md +0 -136
  513. package/docs/assets/humanish-drawdb-hero.png +0 -0
  514. package/docs/assets/humanish-observer-hero.png +0 -0
  515. package/docs/goals/current.md +0 -207
  516. package/docs/product/lobby-trivia-3player-external-public.md +0 -77
  517. package/docs/product/open-source-install-experience.md +0 -240
  518. package/docs/ramp/README.md +0 -295
  519. package/docs/release/open-source-readiness.md +0 -222
  520. package/docs/release/public-readiness-standard.md +0 -210
  521. package/docs/roadmap/world-class-open-source-v0.md +0 -311
@@ -22,31 +22,31 @@ export function planTerminalLab(config, input) {
22
22
  refusal: { route: "terminal", code, message, ...(actor === undefined ? {} : { actor }) },
23
23
  });
24
24
  if (String(config.comms?.email?.kind) === "real")
25
- return refuse("HUMANISH_TERMINAL_LAB_SUBJECT_INVALID", "Real email receiving is unsupported on the terminal route. Use a supported hosted computer-use browser lab.");
25
+ return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", "Real email receiving is unsupported on the terminal route. Use a supported hosted computer-use browser lab.");
26
26
  const mediaReason = desktopMediaValidationReason(config);
27
27
  if (mediaReason)
28
- return refuse("HUMANISH_TERMINAL_LAB_SUBJECT_INVALID", mediaReason);
28
+ return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", mediaReason);
29
29
  const analysis = resolveAutomaticAnalysis(config.review?.analysis);
30
30
  if (!analysis.ok)
31
- return refuse("HUMANISH_LAB_ANALYSIS_INVALID", analysis.message);
31
+ return refuse("HUMANISH_STUDY_ANALYSIS_INVALID", analysis.message);
32
32
  const tasksReason = taskProtocolValidationReason(config, false);
33
33
  if (tasksReason)
34
- return refuse("HUMANISH_LAB_TASKS_UNSUPPORTED", tasksReason);
34
+ return refuse("HUMANISH_STUDY_TASKS_UNSUPPORTED", tasksReason);
35
35
  const actorType = config.actors[0]?.type ?? "";
36
36
  const descriptor = actorRegistry[actorType];
37
37
  if (!descriptor || !isTerminalActorDescriptor(descriptor))
38
- return refuse("HUMANISH_TERMINAL_LAB_ACTOR_UNSUPPORTED", `actors[0].type "${actorType}" is not a registered terminal actor.`);
38
+ return refuse("HUMANISH_TERMINAL_ACTOR_UNSUPPORTED", `actors[0].type "${actorType}" is not a registered terminal actor.`);
39
39
  const runtimeVersion = config.execution?.runtime?.version;
40
40
  const actor = config.actors[0];
41
41
  if ((config.execution?.runtime !== undefined && !isExactRuntimeVersion(runtimeVersion)) ||
42
42
  (actor?.model !== undefined &&
43
43
  (typeof actor.model !== "string" || actor.model.trim().length === 0)) ||
44
44
  (actor?.reasoningEffort !== undefined && !isReasoningEffort(actor.reasoningEffort)))
45
- return refuse("HUMANISH_TERMINAL_LAB_FAILED", "Terminal runtime settings require an exact Codex version, a nonempty model when declared, and a supported reasoning-effort value.");
45
+ return refuse("HUMANISH_TERMINAL_FAILED", "Terminal runtime settings require an exact Codex version, a nonempty model when declared, and a supported reasoning-effort value.");
46
46
  const product = config.subject.product;
47
47
  const surfaces = product?.publicSurfaces ?? [];
48
48
  if (!product || !product.name || !isNonEmpty(surfaces))
49
- return refuse("HUMANISH_TERMINAL_LAB_SUBJECT_INVALID", "terminal-product subjects require `subject.product` with a name and at least one public surface URL.", descriptor.id);
49
+ return refuse("HUMANISH_TERMINAL_SUBJECT_INVALID", "terminal-product subjects require `subject.product` with a name and at least one public surface URL.", descriptor.id);
50
50
  const base = planBase(config, {
51
51
  dryRun: input.dryRun,
52
52
  analysis,
@@ -82,19 +82,19 @@ export function planTerminalLab(config, input) {
82
82
  // that declares that placement may run live.
83
83
  const keyPlacement = descriptor.capabilities.keyPlacement;
84
84
  if (keyPlacement !== "in-sandbox-command-scoped")
85
- return refuse("HUMANISH_TERMINAL_LAB_KEYPLACEMENT_INVALID", `Terminal actor "${descriptor.id}" must declare keyPlacement "in-sandbox-command-scoped" for a live run (got "${String(keyPlacement)}"). The engine requires this registered default before applying the declared runtime-auth mode.`, descriptor.id);
85
+ return refuse("HUMANISH_TERMINAL_KEYPLACEMENT_INVALID", `Terminal actor "${descriptor.id}" must declare keyPlacement "in-sandbox-command-scoped" for a live run (got "${String(keyPlacement)}"). The engine requires this registered default before applying the declared runtime-auth mode.`, descriptor.id);
86
86
  // A live run grants the in-sandbox agent provider access, so a fail-closed cap must be in force.
87
87
  const maxUsd = caps?.maxUsd;
88
88
  const maxMinutes = caps?.maxMinutes;
89
89
  if (caps === undefined || maxUsd === undefined || maxMinutes === undefined || maxMinutes <= 0)
90
- return refuse("HUMANISH_TERMINAL_LAB_CAPS_MISSING", "A live terminal-product run grants provider access to the in-sandbox agent and so REQUIRES a fail-closed cap: scenario.caps with maxUsd (0 = no-spend) and a positive maxMinutes (the codex command's wall-clock kill). The live key is never exercised without a cap in force.", descriptor.id);
90
+ return refuse("HUMANISH_TERMINAL_CAPS_MISSING", "A live terminal-product run gives the agent in the sandbox access to a model provider, so it needs a cap: set scenario.caps with maxUsd (0 means no spend) and a positive maxMinutes (the time limit for the codex command). The key is used only while the cap is in force.", descriptor.id);
91
91
  // maxUsd is checked against the cost ledger after the session, and only known lines can trip it.
92
92
  // The ledger's provider line takes only provider-reported cost, which Codex does not report (the
93
93
  // token estimate in run.json is not a measurement), and core has no product, media or payment
94
94
  // signal, so without a costProbe every line is null and a positive maxUsd could never trip. That
95
95
  // cap would promise a bound nothing enforces, so it is refused; maxMinutes bounds a live run.
96
96
  if (maxUsd > 0 && input.hasCostProbe !== true)
97
- return refuse("HUMANISH_TERMINAL_LAB_UNPRICED_CAP", `scenario.caps.maxUsd=${maxUsd} cannot be enforced: Codex reports no provider cost for the participant (its token cost is only estimated after the run) and no product, media or payment spend is measured, so a positive dollar cap can never trip. Set scenario.caps.maxUsd to 0 and bound the run with scenario.caps.maxMinutes, the codex command's wall-clock kill. No sandbox was created and the runtime key was not used.`, descriptor.id);
97
+ return refuse("HUMANISH_TERMINAL_UNPRICED_CAP", `scenario.caps.maxUsd=${maxUsd} cannot be enforced: Codex reports no provider cost for the participant (its token cost is only estimated after the run) and no product, media or payment spend is measured, so a positive dollar cap can never trip. Set scenario.caps.maxUsd to 0 and bound the run with scenario.caps.maxMinutes, the codex command's wall-clock kill. No sandbox was created and the runtime key was not used.`, descriptor.id);
98
98
  // The sandbox's timeout covers the steps before the codex command, maxMinutes and the teardown
99
99
  // buffer, and E2B refuses a sandbox over an hour. Refuse here, with the arithmetic, rather than
100
100
  // after the plan prints, from a provider 400 that names neither knob.
@@ -102,7 +102,7 @@ export function planTerminalLab(config, input) {
102
102
  const sandboxTimeoutMs = terminalSandboxTimeoutMs({ maxMinutes, productInstall });
103
103
  if (sandboxTimeoutMs > MAX_SANDBOX_MS) {
104
104
  const headroomMinutes = (sandboxTimeoutMs - maxMinutes * 60_000) / 60_000;
105
- return refuse("HUMANISH_TERMINAL_LAB_CAPS_INVALID", `scenario.caps.maxMinutes ${maxMinutes} derives a ${sandboxTimeoutMs / 60_000}m sandbox deadline, and a sandbox may not live longer than ${MAX_SANDBOX_MS / 60_000}m. The deadline is maxMinutes plus ${headroomMinutes}m: the Node bootstrap (${NODE_BOOTSTRAP_TIMEOUT_MS / 60_000}m), the runtime version check (${TERMINAL_RUNTIME_VERSION_TIMEOUT_MS / 60_000}m)${productInstall ? `, the product setup (${PRODUCT_SETUP_TIMEOUT_MS / 60_000}m)` : ""} and the teardown buffer (${TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS / 60_000}m). Lower scenario.caps.maxMinutes to at most ${MAX_SANDBOX_MS / 60_000 - headroomMinutes}. No sandbox was created and the runtime key was not used.`, descriptor.id);
105
+ return refuse("HUMANISH_TERMINAL_CAPS_INVALID", `scenario.caps.maxMinutes ${maxMinutes} derives a ${sandboxTimeoutMs / 60_000}m sandbox deadline, and a sandbox may not live longer than ${MAX_SANDBOX_MS / 60_000}m. The deadline is maxMinutes plus ${headroomMinutes}m: the Node bootstrap (${NODE_BOOTSTRAP_TIMEOUT_MS / 60_000}m), the runtime version check (${TERMINAL_RUNTIME_VERSION_TIMEOUT_MS / 60_000}m)${productInstall ? `, the product setup (${PRODUCT_SETUP_TIMEOUT_MS / 60_000}m)` : ""} and the teardown buffer (${TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS / 60_000}m). Lower scenario.caps.maxMinutes to at most ${MAX_SANDBOX_MS / 60_000 - headroomMinutes}. No sandbox was created and the runtime key was not used.`, descriptor.id);
106
106
  }
107
107
  return {
108
108
  ok: true,
@@ -32,13 +32,13 @@ export function createTerminalRecorder(args) {
32
32
  return;
33
33
  }
34
34
  transcriptBytes += Buffer.byteLength(raw, "utf8");
35
- // Scrub, then redact, at the source (safety contract item 5). Only the participant reader below
35
+ // Scrub, then redact, at the source. Only the participant reader below
36
36
  // sees the raw bytes, and it stores none of them.
37
37
  terminalEvents.push({ at: nowIso(), stream, chunk: sanitize(raw) });
38
38
  if (stream === "stdout")
39
39
  participantText.append(raw);
40
40
  };
41
- // E2B can stream every byte through callbacks and return the same complete output (#667).
41
+ // E2B can stream every byte through callbacks and return the same complete output.
42
42
  // Track transport delivery, independently per stream, rather than deduplicating participant
43
43
  // lines or equal usage records. Hash raw callback bytes before redaction/truncation so the
44
44
  // comparison cannot confuse two values that redact identically or lose capped-away delivery.
@@ -1,5 +1,6 @@
1
1
  import { OUTCOME_POLICIES, participantHarnessFailed, resultOk, } from "../../run/judge.js";
2
- import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
2
+ import {} from "./types.js";
3
+ import { studyResultIdentity } from "../../run/study-result.js";
3
4
  /**
4
5
  * What judge.ts reads from a finished terminal session, after a blown cap has overridden it. It has
5
6
  * no engagement or blocker rule: the agent's nonce-verified marker is its declared outcome.
@@ -52,7 +53,7 @@ export function terminalLabResult(args) {
52
53
  // remaining===0 is the by-id-confirmed-reclaimed state; remaining===1 (still present) and
53
54
  // remaining===-1 (kill(id) itself failed) are both unproven by design.
54
55
  const cleanupProven = cleanup.killed && cleanup.remaining === 0;
55
- // A CONFIG-DECLARED scorer that failed to render a pass (status:"fail" / malformed / throw) fails the
56
+ // A config-declared scorer that failed to render a pass (status:"fail" / malformed / throw) fails the
56
57
  // run result as well as the persisted verdict: the keystone route's declared rubric is a gate, so
57
58
  // its fail must drive exit code. Library callers never set this (additive, back-compat).
58
59
  const ok = resultOk({
@@ -62,10 +63,9 @@ export function terminalLabResult(args) {
62
63
  policy: OUTCOME_POLICIES.terminal,
63
64
  });
64
65
  return {
65
- schema: TERMINAL_PRODUCT_LAB_SCHEMA,
66
+ ...studyResultIdentity("terminal", labId),
66
67
  ok,
67
68
  cwd,
68
- labId,
69
69
  actor: actorId,
70
70
  product: productName,
71
71
  dryRun: false,
@@ -97,12 +97,12 @@ export function terminalLabResult(args) {
97
97
  : {
98
98
  error: {
99
99
  code: (!cleanupProven
100
- ? "HUMANISH_TERMINAL_LAB_CLEANUP_UNPROVEN"
100
+ ? "HUMANISH_TERMINAL_CLEANUP_UNPROVEN"
101
101
  : capFailure !== undefined
102
- ? "HUMANISH_TERMINAL_LAB_CAPS_EXCEEDED"
103
- : "HUMANISH_TERMINAL_LAB_FAILED"),
102
+ ? "HUMANISH_TERMINAL_CAPS_EXCEEDED"
103
+ : "HUMANISH_TERMINAL_FAILED"),
104
104
  message: !cleanupProven
105
- ? `Live terminal-product run could not prove sandbox teardown (killed=${cleanup.killed}, remaining=${cleanup.remaining}): ${cleanup.reason}. A run that cannot prove teardown fails closed.${sessionError !== undefined ? ` Session failure: ${sessionError}` : ""}`
105
+ ? `Live terminal-product run could not prove sandbox teardown (killed=${cleanup.killed}, remaining=${cleanup.remaining}): ${cleanup.reason}. A run that cannot prove its sandbox was removed does not pass.${sessionError !== undefined ? ` Session failure: ${sessionError}` : ""}`
106
106
  : (declaredScorerFailure ??
107
107
  capFailure ??
108
108
  sessionError ??
@@ -8,7 +8,7 @@
8
8
  // live-sandbox.ts and live-finish.ts); a dry plan publishes its contract bundle (dry-run.ts);
9
9
  // 4. automatic analysis of a run that published its final bundle.
10
10
  //
11
- // The safety contract (`docs/goals/terminal-product-lane/goal.md`) is enforced by construction in
11
+ // The safety contract (`docs/history/goals/terminal-product-lane/goal.md`) is enforced by construction in
12
12
  // the files each item names, and checked by the verifier (verify/actor.ts
13
13
  // validateTerminalProductEvidence):
14
14
  // 1. Explicit key placement. openai-env (default) injects the raw runtime key command-scoped,
@@ -20,7 +20,7 @@
20
20
  // (default/require 0 = no-spend) + maxMinutes (wall-clock kill of the codex command).
21
21
  // Enforced in plan.ts (caps required), live-sandbox.ts and lifetime.ts (the wall clock).
22
22
  // 3. Public surfaces only. The mission references only subject.product.publicSurfaces + the
23
- // author mission. No clone, no private-source access — nothing is git-cloned on this route.
23
+ // author mission. No clone and no private-source access: nothing is git-cloned on this route.
24
24
  // Enforced in session.ts, which composes the prompt.
25
25
  // 4. Deny-by-default credentials. The command envs are built from an allowlist holding only the
26
26
  // declared runtime key; GITHUB_TOKEN/GH_TOKEN/payment/deploy/db/media keys are excluded by
@@ -52,7 +52,8 @@ import { runDryTerminalLab } from "./dry-run.js";
52
52
  import { checkLiveTerminalMachine, runLiveTerminalSession } from "./session.js";
53
53
  import { terminalRouteScorer } from "../../lab/adapter-scorer-loader.js";
54
54
  import { withLateScorer } from "../../lab/route-inputs.js";
55
- import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
55
+ import {} from "./types.js";
56
+ import { studyResultIdentity } from "../../run/study-result.js";
56
57
  /**
57
58
  * The config-taking entry point. It plans, returns a refusal with the same envelope and analysis
58
59
  * record the route has always returned, and otherwise runs the plan.
@@ -71,10 +72,9 @@ export async function runTerminalProductLab(options) {
71
72
  export function terminalLabRefusal(options, refusal) {
72
73
  const { config, dryRun } = options;
73
74
  const refused = {
74
- schema: TERMINAL_PRODUCT_LAB_SCHEMA,
75
+ ...studyResultIdentity("terminal", config.id),
75
76
  ok: false,
76
77
  cwd: path.resolve(options.cwd),
77
- labId: config.id,
78
78
  actor: refusal.actor ?? config.actors[0]?.type ?? "",
79
79
  product: config.subject.product?.name ?? "",
80
80
  dryRun,
@@ -141,10 +141,9 @@ function completeTerminalAnalysis(plan, input, result, finished) {
141
141
  function terminalFailure(plan, input, warnings) {
142
142
  const cwd = path.resolve(input.cwd);
143
143
  return (code, message) => ({
144
- schema: TERMINAL_PRODUCT_LAB_SCHEMA,
144
+ ...studyResultIdentity("terminal", plan.labId),
145
145
  ok: false,
146
146
  cwd,
147
- labId: plan.labId,
148
147
  actor: plan.actor,
149
148
  product: plan.product.name,
150
149
  dryRun: plan.dryRun,
@@ -25,7 +25,7 @@ export declare function teardownSandbox(args: {
25
25
  warnings: string[];
26
26
  }): Promise<TerminalLedgers["cleanup"]>;
27
27
  /**
28
- * Race a commands.run promise against the maxMinutes wall-clock (safety contract item 2). The E2B
28
+ * Race a commands.run promise against the maxMinutes wall-clock. The E2B
29
29
  * commands.run timeoutMs is the primary kill; this injected-clock guard is the belt-and-suspenders
30
30
  * backstop so a mock CLI (which ignores timeoutMs) is still bounded and fails closed in CI.
31
31
  */
@@ -98,7 +98,7 @@ export async function teardownSandbox(args) {
98
98
  }
99
99
  }
100
100
  /**
101
- * Race a commands.run promise against the maxMinutes wall-clock (safety contract item 2). The E2B
101
+ * Race a commands.run promise against the maxMinutes wall-clock. The E2B
102
102
  * commands.run timeoutMs is the primary kill; this injected-clock guard is the belt-and-suspenders
103
103
  * backstop so a mock CLI (which ignores timeoutMs) is still bounded and fails closed in CI.
104
104
  */
@@ -22,7 +22,7 @@ export function checkLiveTerminalMachine(plan, input, warnings) {
22
22
  if (maxUsd > 0) {
23
23
  warnings.push(`scenario.caps.maxUsd=${maxUsd} is checked after the session against the lines the costProbe measures; lines it leaves null (unmeasured) never trip it. scenario.caps.maxMinutes bounds the run while it runs.`);
24
24
  }
25
- // --- Safety contract item 4: deny-by-default credentials; build the command-scoped allowlist. ---
25
+ // --- Deny-by-default credentials: build the command-scoped allowlist. ---
26
26
  const runtimeEnv = buildRuntimeAuth({ runtimeAuth: plan.runtime.auth, env });
27
27
  if (!runtimeEnv.ok)
28
28
  return runtimeEnv;
@@ -31,7 +31,7 @@ export function checkLiveTerminalMachine(plan, input, warnings) {
31
31
  if (missingKeys(plan.requirements, env).length > 0) {
32
32
  return {
33
33
  ok: false,
34
- code: "HUMANISH_TERMINAL_LAB_KEYS_MISSING",
34
+ code: "HUMANISH_TERMINAL_KEYS_MISSING",
35
35
  message: `Live terminal-product labs need E2B_API_KEY in the environment (values are never persisted). ${describeMissingKeys(["E2B_API_KEY"], env)}`,
36
36
  };
37
37
  }
@@ -86,7 +86,7 @@ export async function runLiveTerminalSession(args) {
86
86
  modelSource,
87
87
  ...(reasoningEffort === undefined ? {} : { reasoningEffort }),
88
88
  });
89
- recorder.recordLifecycle("terminal-lab.run.created", `Created live terminal-product run ${runId} (actor ${actor}, product ${product.name}). Caps: maxUsd=${maxUsd}, maxMinutes=${maxMinutes}. Subject provenance UNPINNED (public surfaces only).`);
89
+ recorder.recordLifecycle("terminal-lab.run.created", `Created live terminal-product run ${runId} (actor ${actor}, product ${product.name}). Caps: maxUsd=${maxUsd}, maxMinutes=${maxMinutes}. Subject provenance: unpinned (public pages only).`);
90
90
  const session = new LiveTerminalSandbox({
91
91
  plan,
92
92
  cwd,
@@ -101,7 +101,7 @@ export async function runLiveTerminalSession(args) {
101
101
  maxMinutes,
102
102
  e2bApiKey,
103
103
  runPaths,
104
- metadata: buildSandboxMetadata({ labId: plan.labId, simId: "sim-001", runId }),
104
+ metadata: buildSandboxMetadata({ labId: plan.labId, recordId: "sim-001", runId }),
105
105
  warnings,
106
106
  recorder,
107
107
  });
@@ -146,7 +146,7 @@ export async function runLiveTerminalSession(args) {
146
146
  async function prepareLivePrompt(args) {
147
147
  const { plan, cwd, runtimeEnv, env, warnings } = args;
148
148
  const { product } = plan;
149
- // Compose the prompt from public surfaces and the author mission alone (safety contract item 3).
149
+ // Compose the prompt from public surfaces and the author mission alone.
150
150
  // Inject a per-run verdict nonce: the agent echoes HUMANISH_ACTOR_VERDICT=<status>
151
151
  // HUMANISH_ACTOR_NONCE=<nonce>; the scorer verifies the nonce so replayed text cannot forge it.
152
152
  const mission = plan.mission ?? defaultMission(product.name);
@@ -160,10 +160,10 @@ async function prepareLivePrompt(args) {
160
160
  verdictNonce,
161
161
  });
162
162
  const promptDigest = digestText(composedPrompt);
163
- // --- Safety contract item 5: literal-scrub every known value, then pattern-redact, at the source. ---
163
+ // --- Literal-scrub every known value, then pattern-redact, at the source. ---
164
164
  // The runtime key value (+ any other provisioned value) is scrubbed by literal match before
165
165
  // anything persists (a key has no detectable "shape" if it is an arbitrary token); redactText is
166
- // the second pass for secret-SHAPED content. Applied PRE-truncation so a cut can never split a
166
+ // the second pass for secret-shaped content. Applied pre-truncation so a cut can never split a
167
167
  // value past the scrubber.
168
168
  const knownSecretValues = [runtimeEnv.keyValue, env.E2B_API_KEY?.trim() ?? ""].filter((v) => v.length >= 4);
169
169
  const scrubKnownValues = scrubLiterals(knownSecretValues);
@@ -181,6 +181,7 @@ async function prepareLivePrompt(args) {
181
181
  }
182
182
  /** Compose the live prompt: public surfaces + author mission + the verdict-nonce marker contract. */
183
183
  function composeLivePrompt(args) {
184
+ // prose-check: model prompt (the terminal agent reads this, not a person)
184
185
  return [
185
186
  args.personaLine,
186
187
  `product: ${args.productName}`,
@@ -3,7 +3,7 @@ import type { ActorTokenUsage } from "../../actors/contract.js";
3
3
  * Accumulate runtime-turn usage from a captured `codex exec --json` stream. A Codex turn may
4
4
  * include multiple provider requests; these records cannot establish per-request pricing tiers.
5
5
  *
6
- * Returns undefined when the stream carried no usage record at all, which is the honest "no
6
+ * Returns undefined when the stream carried no usage record at all, which is the "no
7
7
  * signal" case and must stay distinguishable from a measured zero. Per-turn records are preserved
8
8
  * in `turns` because long-context pricing can only be computed from per-request sizes
9
9
  * (src/run/pricing.ts), and totals cannot say which requests crossed a threshold.
@@ -1,10 +1,9 @@
1
- // Provider token accounting for the terminal route (#531).
1
+ // Provider token accounting for the terminal route.
2
2
  //
3
- // The gap this closes: a live terminal run reported `cost.lines.provider = null` with source
4
- // "unmeasured", and the no-spend proof then read `satisfied: true` for `maxUsd: 0` on a run that
5
- // had demonstrably consumed hundreds of thousands of provider tokens. The statement was honest
6
- // (it listed provider as unmeasured) but it conflated two very different states: having no signal
7
- // at all, and knowing exactly how many tokens were spent while lacking a rate to price them.
3
+ // Without these counts, a provider line of `null` with source "unmeasured" would let the no-spend
4
+ // proof read `satisfied: true` for `maxUsd: 0` on a run that consumed hundreds of thousands of
5
+ // provider tokens, conflating two different states: having no signal at all, and knowing exactly
6
+ // how many tokens were spent while lacking a rate to price them.
8
7
  //
9
8
  // The counts were already in the bundle. `codex exec --json` emits one usage record per turn:
10
9
  // {"type":"turn.completed","usage":{"input_tokens":201536,"cached_input_tokens":170558,
@@ -12,7 +11,7 @@
12
11
  //
13
12
  // So the route can record a measured token fact even when it cannot record a priced one. Rates stay
14
13
  // out of this module deliberately: pricing lives in src/run/pricing.ts, and the terminal route has no
15
- // real model id to price against (it records `model: "codex"`), so the honest output is
14
+ // real model id to price against (it records `model: "codex"`), so the output is
16
15
  // tokens-known-rate-unknown rather than a guessed dollar figure.
17
16
  // Bounded to a single line on purpose. `[^}]*` would run past a truncated record's missing brace
18
17
  // and swallow the next, valid record's body, silently dropping a real turn from the count.
@@ -24,7 +23,7 @@ function num(value) {
24
23
  * Accumulate runtime-turn usage from a captured `codex exec --json` stream. A Codex turn may
25
24
  * include multiple provider requests; these records cannot establish per-request pricing tiers.
26
25
  *
27
- * Returns undefined when the stream carried no usage record at all, which is the honest "no
26
+ * Returns undefined when the stream carried no usage record at all, which is the "no
28
27
  * signal" case and must stay distinguishable from a measured zero. Per-turn records are preserved
29
28
  * in `turns` because long-context pricing can only be computed from per-request sizes
30
29
  * (src/run/pricing.ts), and totals cannot say which requests crossed a threshold.
@@ -12,7 +12,7 @@ export declare function scrubSplitKnownValues(events: TerminalEventRecord[], kno
12
12
  export declare function tailOf(text: string): string;
13
13
  /**
14
14
  * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
15
- * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
15
+ * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement
16
16
  * guard (a real run bumps them; a no-op is caught). No screenshots on this route.
17
17
  */
18
18
  export declare function buildTerminalActorTrace(args: {
@@ -29,7 +29,7 @@ export declare function buildTerminalActorTrace(args: {
29
29
  transcriptTail: string;
30
30
  runtimeAuth: LabRuntimeAuth;
31
31
  runtime: ActorRuntimeProvenance;
32
- /** Runtime-turn aggregate usage parsed from the exec stream (#531). Absent when the stream
32
+ /** Runtime-turn aggregate usage parsed from the exec stream. Absent when the stream
33
33
  * carried no usage record, which stays distinct from a measured zero. */
34
34
  tokenUsage?: ActorTokenUsage;
35
35
  /** The agent's own text and activity, read from the raw stdout as it arrived. */
@@ -57,7 +57,7 @@ export function tailOf(text) {
57
57
  }
58
58
  /**
59
59
  * Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
60
- * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
60
+ * "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement
61
61
  * guard (a real run bumps them; a no-op is caught). No screenshots on this route.
62
62
  */
63
63
  export function buildTerminalActorTrace(args) {
@@ -88,7 +88,7 @@ export function buildTerminalActorTrace(args) {
88
88
  redaction: {
89
89
  status: "passed",
90
90
  screenshots: "n/a",
91
- notes: "Terminal exec output captured via commands.run onStdout/onStderr, scrubbed (literal known values) then redacted (shape patterns) AT THE SOURCE before persisting; no screenshots on this lane.",
91
+ notes: "Terminal output captured through commands.run onStdout and onStderr; known values are scrubbed and shape patterns redacted before anything is stored. This route takes no screenshots.",
92
92
  },
93
93
  startedAt: args.createdAt,
94
94
  completedAt: args.completedAt,
@@ -9,6 +9,7 @@ import type { LabDeps } from "../../lab/lab-deps.js";
9
9
  import type { LabConfig } from "../../lab/types.js";
10
10
  import type { ObserverResult } from "../../observer/render.js";
11
11
  import { type RunAdapterScore, type RunBundle, type RunFeedbackCandidate, type RunScorerProvenance } from "../../run/bundle.js";
12
+ import { type StudyResultIdentity } from "../../run/study-result.js";
12
13
  /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
13
14
  export declare const TERMINAL_PRODUCT_LAB_PROVIDER_METADATA: {
14
15
  readonly mode: "terminal-product-lab";
@@ -22,7 +23,7 @@ export declare const UPLOAD_MAX_BYTES: number;
22
23
  /**
23
24
  * Server-side reclamation buffer past the codex command's own wall-clock (caps.maxMinutes) kill.
24
25
  * Shorter than the desktop routes' SANDBOX_TIMEOUT_BUFFER_MS (src/substrates/e2b/lifetime.ts):
25
- * when #158 set it, the terminal sandbox ran nothing but the codex command, and after its kill only
26
+ * when this buffer was set, the terminal sandbox ran nothing but the codex command, and after its kill only
26
27
  * teardown remained.
27
28
  */
28
29
  export declare const TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS: number;
@@ -34,13 +35,12 @@ export declare const TEXT_ITEMS_MAX = 200;
34
35
  export declare const TEXT_ITEMS_BYTES: number;
35
36
  export declare const PENDING_LINE_CHARS: number;
36
37
  export declare const MAX_TRANSCRIPT_BYTES: number;
37
- export declare const TERMINAL_PRODUCT_LAB_SCHEMA = "humanish.terminal-lab-result.v1";
38
38
  /**
39
- * The read-only evidence a thin adapter's scorer/feedback hook sees (the layer-6 extension seam,
40
- * issue #154 acceptance #8). It is the FULLY-ASSEMBLED, redacted, verifiable evidence — the live run
39
+ * The read-only evidence a thin adapter's scorer/feedback hook sees (the adapter extension seam).
40
+ * It is the fully assembled, redacted, verifiable evidence: the live run
41
41
  * bundle, the provider-neutral actor trace, and the persisted ledgers (substrate/command/
42
42
  * interventions/cleanup/cost/no-spend). Every member is an exported public type, so a thin adapter
43
- * types against `import("humanish")` alone — never a deep `src/` import. The adapter reads this
43
+ * types against `import("humanish")` alone and never needs a deep `src/` import. The adapter reads this
44
44
  * to score the product attempt and derive feedback; it cannot mutate core's evidence (the route
45
45
  * attaches only the namespaced `RunAdapterScore` it returns + the feedback candidates it derives).
46
46
  */
@@ -56,7 +56,7 @@ export interface TerminalProductScoringContext {
56
56
  * values) then redacted (shape patterns) at the source, capped at MAX_TRANSCRIPT_BYTES, and
57
57
  * byte-identical to the persisted terminal-transcript.txt artifact. The trace's transcriptTail
58
58
  * is a ~2KB projection of this; a scorer needs the whole session so a rubric can find
59
- * command-tier evidence anywhere in it, not only in the tail window (#341).
59
+ * command-tier evidence anywhere in it.
60
60
  */
61
61
  transcript: string;
62
62
  /** The studied product name (public-safe). */
@@ -77,9 +77,9 @@ export type TerminalCostProbe = (context: {
77
77
  /** The scorer functions a terminal run calls: `RunLabOptions.scorer` without `deriveArtifacts`. */
78
78
  export interface TerminalScorer {
79
79
  /**
80
- * The layer-6 extension seam (issue #154 acceptance #8: "product-adapter hooks without forking
81
- * core"). A thin in-repo/out-of-tree adapter registers a product scorer here. The route calls it
82
- * (when provided) over the fully-assembled evidence and attaches the returned, ADAPTER-NAMESPACED
80
+ * The adapter extension seam: product-adapter hooks without forking
81
+ * core. A thin in-repo/out-of-tree adapter registers a product scorer here. The route calls it
82
+ * (when provided) over the fully-assembled evidence and attaches the returned, adapter-namespaced
83
83
  * `RunAdapterScore` to `bundle.adapterScore` without core knowing any product noun (the score is
84
84
  * namespaced + its component breakdown rides in `data`). When no scorer is given, the default
85
85
  * mission-based verdict (`review`) is unchanged. The adopter's scorecard plugs in here; product
@@ -90,9 +90,9 @@ export interface TerminalScorer {
90
90
  * Companion seam: derive product-feedback candidates from the same assembled evidence. The route
91
91
  * appends the returned candidates to `bundle.feedbackCandidates`. The adapter records its
92
92
  * product-specific concepts (public CLI command observed, hosted success-or-blocker, feedback id,
93
- * media/job ids, no-spend proof, defection/friction risk) under each candidate's ADAPTER-NAMESPACED
94
- * `adapter` block — never as core enums (issue #154's "record product-specific concepts as
95
- * NON-core nouns" list). The candidates must still satisfy core's feedback-candidate shape (which
93
+ * media/job ids, no-spend proof, defection/friction risk) under each candidate's adapter-namespaced
94
+ * `adapter` block and never as core enums.
95
+ * The candidates must still satisfy core's feedback-candidate shape (which
96
96
  * the bundle verifier enforces), so a malformed adapter candidate fails closed.
97
97
  */
98
98
  deriveFeedback?: (ctx: TerminalProductScoringContext) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
@@ -119,7 +119,7 @@ export interface RunTerminalProductLabOptions {
119
119
  /** Test seams: the E2B module, the Observer renderer, the clock and the cost probe. */
120
120
  deps?: LabDeps;
121
121
  /**
122
- * Present only when the scorer was config-declared and loaded by the CLI (#316). Its presence
122
+ * Present only when the scorer was config-declared and loaded by the CLI. Its presence
123
123
  * is the "declared" marker: a config-declared terminal scorer returning status:"fail" flips
124
124
  * bundle.review.verdict (like the browser routes), and one that throws becomes a visible review.gaps
125
125
  * entry. A library caller passing `scorer` leaves this absent and keeps today's purely
@@ -127,14 +127,12 @@ export interface RunTerminalProductLabOptions {
127
127
  */
128
128
  scorerProvenance?: RunScorerProvenance;
129
129
  }
130
- export interface TerminalProductLabResult extends AutomaticAnalysisResult {
131
- schema: typeof TERMINAL_PRODUCT_LAB_SCHEMA;
130
+ export interface TerminalProductLabResult extends AutomaticAnalysisResult, StudyResultIdentity<"terminal"> {
132
131
  /** True when the bundle verified and (dry-run, or the live session reached a terminal verdict
133
132
  * without a harness error + cleanup was proven). The agent's pass/fail is evidence, not the
134
133
  * lab's exit code. */
135
134
  ok: boolean;
136
135
  cwd: string;
137
- labId: string;
138
136
  /** The registry-resolved actor id that ran (or would run) the session. */
139
137
  actor: string;
140
138
  /** The studied product name (public-safe). */
@@ -151,11 +149,11 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult {
151
149
  sandbox?: {
152
150
  sandboxId: string;
153
151
  killed: boolean;
154
- /** BY-ID proof (never a re-list): 0 = confirmed reclaimed, 1 = still present (unconfirmed),
152
+ /** By-id proof (never a re-list): 0 = confirmed reclaimed, 1 = still present (unconfirmed),
155
153
  * -1 = kill(id) itself failed or was unavailable. See TerminalLedgers["cleanup"]. */
156
154
  remaining: number;
157
155
  };
158
- /** Live-only: the spend ledger surfaced on the result — unknowns are null, never guessed.
156
+ /** Live-only: the spend ledger surfaced on the result. Unknowns are null, never guessed.
159
157
  * Lets a programmatic caller read spend without parsing the bundle. */
160
158
  cost?: {
161
159
  knownTotalUsd: number;
@@ -173,7 +171,7 @@ export interface TerminalProductLabResult extends AutomaticAnalysisResult {
173
171
  observer?: ObserverResult;
174
172
  warnings: string[];
175
173
  error?: {
176
- code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_FAILED" | "HUMANISH_TERMINAL_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_LAB_SUBJECT_INVALID" | "HUMANISH_TERMINAL_LAB_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_LAB_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_LAB_KEYS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_MISSING" | "HUMANISH_TERMINAL_LAB_CAPS_INVALID" | "HUMANISH_TERMINAL_LAB_UNPRICED_CAP" | "HUMANISH_TERMINAL_LAB_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_LAB_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_LAB_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE";
174
+ code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_TERMINAL_FAILED" | "HUMANISH_TERMINAL_ACTOR_UNSUPPORTED" | "HUMANISH_TERMINAL_SUBJECT_INVALID" | "HUMANISH_TERMINAL_KEYPLACEMENT_INVALID" | "HUMANISH_TERMINAL_RUNTIME_AUTH_MISSING" | "HUMANISH_TERMINAL_KEYS_MISSING" | "HUMANISH_TERMINAL_CAPS_MISSING" | "HUMANISH_TERMINAL_CAPS_INVALID" | "HUMANISH_TERMINAL_UNPRICED_CAP" | "HUMANISH_TERMINAL_CAPS_EXCEEDED" | "HUMANISH_TERMINAL_CREDENTIAL_DENIED" | "HUMANISH_TERMINAL_CLEANUP_UNPROVEN" | "HUMANISH_RUN_ID_IN_USE";
177
175
  message: string;
178
176
  };
179
177
  }
@@ -189,7 +187,7 @@ export interface CommandLogRecord {
189
187
  at: string;
190
188
  /** A public-safe label for the command (e.g. "codex-exec"); the full argv is bound by digest only. */
191
189
  label: string;
192
- /** sha256-12 of the exact command string — pins "same recipe" without persisting it. */
190
+ /** sha256-12 of the exact command string. It pins "same recipe" without persisting it. */
193
191
  commandDigest: string;
194
192
  /** The env var names injected command-scoped (values never persisted): the credential evidence. */
195
193
  envNames: string[];
@@ -216,7 +214,7 @@ export interface InterventionRecord {
216
214
  inputDigest: string;
217
215
  }
218
216
  /**
219
- * One cost line of the spend ledger. The null discipline (issue #154, the cost/no-spend asks):
217
+ * One cost line of the spend ledger. The null discipline:
220
218
  * three distinct states are kept apart:
221
219
  * - `usd: 0` => known to be zero. A measured-and-zero spend (we metered this category and it
222
220
  * billed nothing). The no-spend proof may legitimately assert this is zero.
@@ -226,7 +224,7 @@ export interface InterventionRecord {
226
224
  * - line absent => not applicable to this route/run (n/a). The line simply does not appear in
227
225
  * `lines`. (The current route emits all four lines, so absence is reserved for
228
226
  * future routes that genuinely have no such category.)
229
- * `null` vs missing-key is the load-bearing distinction: a missing key means "this category does not
227
+ * `null` vs missing-key is the distinction that matters: a missing key means "this category does not
230
228
  * exist for this run"; a present key with `null` means "this category exists but we did not measure
231
229
  * it". A no-spend proof that claimed zero on a `null` line would claim more than it measured.
232
230
  */
@@ -238,7 +236,7 @@ export interface CostLine {
238
236
  /** How this line's value was established (provenance for the verifier + the human reviewer). */
239
237
  source: "provider-token-usage" | "no-spend-signal" | "operator-cap" | "unmeasured"
240
238
  /** Tokens were counted but no rate could price them, so `usd` stays null while the note
241
- * carries the measured token totals (#531). Distinct from "unmeasured", which means no
239
+ * carries the measured token totals. Distinct from "unmeasured", which means no
242
240
  * signal at all. */
243
241
  | "unpriced-token-usage";
244
242
  /** A short, public-safe note (never a secret value). */
@@ -260,8 +258,8 @@ export interface TerminalCostLedger {
260
258
  fullyMeasured: boolean;
261
259
  }
262
260
  /**
263
- * The no-spend proof, derived from the cost ledger (issue #154: "derived from a ledger, not
264
- * asserted"). It lists the known-zero lines it can vouch for and, separately, the unmeasured
261
+ * The no-spend proof, derived from the cost ledger.
262
+ * It lists the known-zero lines it can vouch for and, separately, the unmeasured
265
263
  * (null) lines it cannot vouch for. `satisfied` is true only when every known line is zero (a
266
264
  * known non-zero line fails it). A proof with unmeasured lines says it could not measure them;
267
265
  * it never claims zero on a line the ledger marks null.
@@ -274,14 +272,14 @@ export interface NoSpendProof {
274
272
  satisfied: boolean;
275
273
  /** Categories the ledger measured and found at (known) zero: the proof can vouch for these. */
276
274
  knownZeroLines: CostCategory[];
277
- /** Categories the ledger measured with a known NON-zero spend (these break `satisfied`). */
275
+ /** Categories the ledger measured with a known non-zero spend (these break `satisfied`). */
278
276
  knownNonZeroLines: CostCategory[];
279
277
  /** Categories the ledger marks `null` (not measured). The proof lists these and does not claim
280
278
  * they are zero; it claims only that this run could not measure them. */
281
279
  unmeasuredLines: CostCategory[];
282
280
  /** Sum of the known lines (== 0 for a satisfied no-spend run). */
283
281
  knownTotalUsd: number;
284
- /** Human-readable honesty statement covering both what is proven and what is unmeasured. */
282
+ /** Human-readable statement covering both what is proven and what is unmeasured. */
285
283
  statement: string;
286
284
  }
287
285
  /** The persisted terminal-product ledgers artifact (substrate lifecycle + command log + interventions + cleanup + cost). */
@@ -302,7 +300,7 @@ export interface TerminalLedgers {
302
300
  * this exact sandbox running/paused (still present); -1 = kill(id) itself failed, threw, or
303
301
  * was unavailable (the server-side kill-on-timeout is the backstop). */
304
302
  remaining: number;
305
- /** Honest, human-readable statement of which by-id signal produced `remaining`. */
303
+ /** Human-readable statement of which by-id signal produced `remaining`. */
306
304
  reason: string;
307
305
  };
308
306
  /** The spend ledger. Unknowns are `null`, never guessed; the no-spend proof
@@ -1,5 +1,6 @@
1
1
  import {} from "../../analysis/automatic-completion.js";
2
2
  import {} from "../../run/bundle.js";
3
+ import {} from "../../run/study-result.js";
3
4
  /** Provider-neutral metadata constant: the route's non-secret tag (mirrors CUA_ACTOR_LAB_PROVIDER_METADATA). */
4
5
  export const TERMINAL_PRODUCT_LAB_PROVIDER_METADATA = {
5
6
  mode: "terminal-product-lab",
@@ -13,7 +14,7 @@ export const UPLOAD_MAX_BYTES = 64 * 1024 * 1024;
13
14
  /**
14
15
  * Server-side reclamation buffer past the codex command's own wall-clock (caps.maxMinutes) kill.
15
16
  * Shorter than the desktop routes' SANDBOX_TIMEOUT_BUFFER_MS (src/substrates/e2b/lifetime.ts):
16
- * when #158 set it, the terminal sandbox ran nothing but the codex command, and after its kill only
17
+ * when this buffer was set, the terminal sandbox ran nothing but the codex command, and after its kill only
17
18
  * teardown remained.
18
19
  */
19
20
  export const TERMINAL_SANDBOX_TIMEOUT_BUFFER_MS = 5 * 60_000;
@@ -31,6 +32,5 @@ export const TEXT_ITEMS_BYTES = 128 * 1024;
31
32
  // The longest stdout line the participant reader holds while waiting for its newline.
32
33
  export const PENDING_LINE_CHARS = 1024 * 1024;
33
34
  // Hard cap on the retained event-stream + transcript size, so a runaway agent cannot balloon the
34
- // bundle. Redaction runs PRE-truncation so a cut can never split a secret past the scrubber.
35
+ // bundle. Redaction runs pre-truncation so a cut can never split a secret past the scrubber.
35
36
  export const MAX_TRANSCRIPT_BYTES = 512 * 1024;
36
- export const TERMINAL_PRODUCT_LAB_SCHEMA = "humanish.terminal-lab-result.v1";
@@ -156,9 +156,9 @@ function isDesktopBrowserEvidence(value) {
156
156
  }
157
157
  /** Short lowercase-hex content digest (digestText default is 12 chars; tolerate longer future digests). */
158
158
  const SCORER_DIGEST_PATTERN = /^[a-f0-9]{12,64}$/;
159
- /** Shape guard for RunScorerProvenance (#316), mirroring isRunSubjectProvenance: tolerated-absent in
159
+ /** Shape guard for RunScorerProvenance, mirroring isRunSubjectProvenance: tolerated-absent in
160
160
  * isRunBundle, well-shaped when present. Semantics (does the digest still match the file) are not a
161
- * verify concern — the block is core-stamped evidence of what was loaded, not a re-execution proof. */
161
+ * verify concern: the block is core-stamped evidence of what was loaded and proves no re-execution. */
162
162
  function isRunScorerProvenance(value) {
163
163
  return (isRecord(value) &&
164
164
  value.schema === "humanish.scorer-provenance.v1" &&
@@ -183,7 +183,7 @@ export function isRunAdapterScore(value) {
183
183
  (value.data === undefined || isRecord(value.data)));
184
184
  }
185
185
  // The local-tree archive content pin: sha256 hex, full 64 chars (unlike the repo's 16-char
186
- // display-digest convention -- this value is the provenance pin itself, persisted in full).
186
+ // display-digest convention; this value is the provenance pin itself, persisted in full).
187
187
  export const ARCHIVE_SHA256_PATTERN = /^[a-f0-9]{64}$/;
188
188
  function isRunSubjectProvenance(value) {
189
189
  if (!isRecord(value))