humanish 0.106.1 → 0.107.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 (453) hide show
  1. package/AGENTS.md +4 -4
  2. package/ARCHITECTURE.md +17 -16
  3. package/CHANGELOG.md +14 -0
  4. package/CONTEXT.md +42 -39
  5. package/CONTRIBUTING.md +8 -8
  6. package/README.md +8 -3
  7. package/dist/actors/codex/app-server-client.js +2 -1
  8. package/dist/actors/codex/app-server-trace.d.ts +0 -1
  9. package/dist/actors/codex/app-server-trace.js +1 -3
  10. package/dist/actors/codex/app-server.js +2 -1
  11. package/dist/actors/codex/protocol-compat.d.ts +27 -0
  12. package/dist/actors/codex/protocol-compat.js +357 -0
  13. package/dist/actors/codex/protocol-contract.d.ts +61 -0
  14. package/dist/actors/codex/protocol-contract.js +471 -0
  15. package/dist/actors/codex/qualified-versions.d.ts +30 -3
  16. package/dist/actors/codex/qualified-versions.js +50 -5
  17. package/dist/actors/codex/restricted-executable.d.ts +24 -0
  18. package/dist/actors/codex/restricted-executable.js +97 -22
  19. package/dist/actors/codex/restricted-launch.d.ts +7 -1
  20. package/dist/actors/codex/restricted-launch.js +42 -3
  21. package/dist/actors/codex/restricted-notifications.d.ts +101 -0
  22. package/dist/actors/codex/restricted-notifications.js +277 -0
  23. package/dist/actors/codex/restricted-participant.d.ts +30 -0
  24. package/dist/actors/codex/restricted-participant.js +60 -2
  25. package/dist/actors/codex/restricted-policy.d.ts +9 -1
  26. package/dist/actors/codex/restricted-session.d.ts +14 -1
  27. package/dist/actors/codex/restricted-session.js +50 -17
  28. package/dist/actors/codex/restricted-transport.d.ts +29 -0
  29. package/dist/actors/codex/restricted-transport.js +139 -27
  30. package/dist/actors/codex/restricted-turn.d.ts +19 -4
  31. package/dist/actors/codex/restricted-turn.js +43 -30
  32. package/dist/actors/computer-use/actor.d.ts +1 -1
  33. package/dist/actors/computer-use/actor.js +4 -4
  34. package/dist/actors/computer-use/loop/backstop.js +1 -1
  35. package/dist/actors/computer-use/loop/ending.d.ts +2 -2
  36. package/dist/actors/computer-use/loop/ending.js +2 -2
  37. package/dist/actors/computer-use/loop/spend.d.ts +1 -1
  38. package/dist/actors/computer-use/loop/spend.js +3 -3
  39. package/dist/actors/computer-use/loop/trace.js +2 -2
  40. package/dist/actors/computer-use/loop/types.d.ts +14 -5
  41. package/dist/actors/computer-use/loop.js +4 -4
  42. package/dist/actors/computer-use/openai-provider.d.ts +1 -1
  43. package/dist/actors/computer-use/openai-provider.js +2 -2
  44. package/dist/actors/contract.d.ts +9 -7
  45. package/dist/actors/local-agent/cli.js +1 -1
  46. package/dist/actors/scripted-browser/actor.d.ts +2 -2
  47. package/dist/actors/scripted-browser/journey.js +15 -4
  48. package/dist/actors/scripted-browser/steps.js +18 -0
  49. package/dist/actors/scripted-browser/types.d.ts +11 -1
  50. package/dist/actors/stop-conditions.js +1 -3
  51. package/dist/analysis/automatic-completion.d.ts +13 -8
  52. package/dist/analysis/automatic-completion.js +14 -8
  53. package/dist/analysis/automatic-config.d.ts +1 -1
  54. package/dist/analysis/automatic-config.js +2 -2
  55. package/dist/analysis/automatic.d.ts +10 -4
  56. package/dist/analysis/automatic.js +17 -13
  57. package/dist/analysis/diagnostics.d.ts +23 -0
  58. package/dist/analysis/diagnostics.js +112 -0
  59. package/dist/analysis/evidence-sources.js +2 -2
  60. package/dist/analysis/evidence.js +6 -6
  61. package/dist/analysis/execute.d.ts +7 -1
  62. package/dist/analysis/execute.js +39 -12
  63. package/dist/analysis/job.d.ts +8 -5
  64. package/dist/analysis/job.js +15 -14
  65. package/dist/analysis/load.d.ts +1 -1
  66. package/dist/analysis/load.js +5 -5
  67. package/dist/analysis/provider.d.ts +9 -1
  68. package/dist/analysis/restricted-codex.d.ts +2 -0
  69. package/dist/analysis/restricted-codex.js +10 -1
  70. package/dist/analysis/service.d.ts +2 -0
  71. package/dist/analysis/service.js +31 -12
  72. package/dist/analysis/sharing.d.ts +2 -2
  73. package/dist/analysis/sharing.js +5 -5
  74. package/dist/analysis/store-executions.d.ts +5 -5
  75. package/dist/analysis/store-executions.js +12 -12
  76. package/dist/analysis/store.d.ts +4 -4
  77. package/dist/analysis/store.js +13 -13
  78. package/dist/cli/commands/analysis-signals.d.ts +2 -1
  79. package/dist/cli/commands/analysis-signals.js +4 -1
  80. package/dist/cli/commands/analyze.js +4 -2
  81. package/dist/cli/commands/comms.js +8 -1
  82. package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
  83. package/dist/cli/commands/lab-route-computer-use.js +26 -14
  84. package/dist/cli/commands/lab-route-preview.d.ts +1 -3
  85. package/dist/cli/commands/lab-route-preview.js +3 -4
  86. package/dist/cli/commands/lab-route-run.d.ts +6 -4
  87. package/dist/cli/commands/lab-route-run.js +6 -2
  88. package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
  89. package/dist/cli/commands/lab-route-scripted.js +0 -1
  90. package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
  91. package/dist/cli/commands/lab-route-shared-world.js +0 -1
  92. package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
  93. package/dist/cli/commands/lab-route-terminal.js +0 -1
  94. package/dist/cli/commands/lab-run.js +76 -45
  95. package/dist/cli/commands/lab-scorer.d.ts +0 -2
  96. package/dist/cli/commands/lab.js +12 -6
  97. package/dist/cli/commands/observe.js +22 -0
  98. package/dist/cli/commands/run-signals.d.ts +30 -0
  99. package/dist/cli/commands/run-signals.js +146 -0
  100. package/dist/cli/commands/runs.js +10 -8
  101. package/dist/cli/commands/watch.js +12 -10
  102. package/dist/cli/doctor.d.ts +3 -0
  103. package/dist/cli/doctor.js +10 -2
  104. package/dist/cli/io.d.ts +5 -4
  105. package/dist/cli/io.js +12 -8
  106. package/dist/cli/program.js +3 -3
  107. package/dist/cli/renamed-options.d.ts +11 -0
  108. package/dist/cli/renamed-options.js +18 -0
  109. package/dist/cli/telemetry.d.ts +2 -2
  110. package/dist/cli/telemetry.js +1 -1
  111. package/dist/comms/capture-surface.d.ts +1 -1
  112. package/dist/comms/catch-host.d.ts +1 -1
  113. package/dist/comms/connections.js +4 -4
  114. package/dist/comms/external-evidence.d.ts +27 -0
  115. package/dist/comms/external-evidence.js +93 -0
  116. package/dist/comms/lease-store.js +7 -7
  117. package/dist/comms/types.js +1 -1
  118. package/dist/evidence/browser-hygiene.d.ts +1 -1
  119. package/dist/evidence/browser-hygiene.js +1 -1
  120. package/dist/evidence/redaction.js +1 -1
  121. package/dist/evidence/secret-scrub.d.ts +9 -0
  122. package/dist/evidence/secret-scrub.js +96 -0
  123. package/dist/feedback/draft.js +7 -9
  124. package/dist/feedback/export-bundle.js +4 -4
  125. package/dist/feedback/export.js +9 -9
  126. package/dist/feedback/feedback.d.ts +1 -1
  127. package/dist/index.d.ts +3 -6
  128. package/dist/index.js +3 -6
  129. package/dist/keys/key-resolution.d.ts +3 -1
  130. package/dist/keys/key-resolution.js +18 -16
  131. package/dist/lab/adapter-extension.d.ts +28 -6
  132. package/dist/lab/adapter-extension.js +65 -126
  133. package/dist/lab/adapter-scorer-loader.d.ts +25 -5
  134. package/dist/lab/adapter-scorer-loader.js +24 -0
  135. package/dist/lab/composition-rules.js +20 -20
  136. package/dist/lab/config.js +28 -26
  137. package/dist/lab/device-presets.d.ts +2 -2
  138. package/dist/lab/discover.js +1 -3
  139. package/dist/lab/doctor.d.ts +44 -9
  140. package/dist/lab/doctor.js +149 -41
  141. package/dist/lab/init-plan.js +1 -3
  142. package/dist/lab/keys.js +1 -1
  143. package/dist/lab/lab-deps.d.ts +85 -0
  144. package/dist/lab/lab-deps.js +4 -0
  145. package/dist/lab/parse/actors.js +8 -7
  146. package/dist/lab/parse/comms.js +3 -2
  147. package/dist/lab/parse/execution.js +3 -2
  148. package/dist/lab/parse/subject-state.js +2 -1
  149. package/dist/lab/parse/subject.js +2 -1
  150. package/dist/lab/parse/values.d.ts +0 -1
  151. package/dist/lab/parse/values.js +0 -3
  152. package/dist/lab/persona-resolve.d.ts +3 -3
  153. package/dist/lab/persona-resolve.js +4 -4
  154. package/dist/lab/persona.js +1 -3
  155. package/dist/lab/plan-base.d.ts +0 -2
  156. package/dist/lab/plan-base.js +6 -4
  157. package/dist/lab/plan-participants.d.ts +5 -5
  158. package/dist/lab/plan-participants.js +2 -2
  159. package/dist/lab/plan-types.d.ts +22 -4
  160. package/dist/lab/plan.d.ts +3 -11
  161. package/dist/lab/plan.js +18 -42
  162. package/dist/lab/preflight-result.js +0 -2
  163. package/dist/lab/preflight.d.ts +0 -3
  164. package/dist/lab/preflight.js +1 -1
  165. package/dist/lab/requirements.d.ts +20 -0
  166. package/dist/lab/requirements.js +54 -0
  167. package/dist/lab/route-inputs.d.ts +23 -12
  168. package/dist/lab/route-inputs.js +48 -51
  169. package/dist/lab/routing.d.ts +19 -24
  170. package/dist/lab/routing.js +14 -47
  171. package/dist/lab/run-lab-events.d.ts +6 -11
  172. package/dist/lab/run-lab-events.js +3 -11
  173. package/dist/lab/run-lab-homes.d.ts +64 -0
  174. package/dist/lab/run-lab-homes.js +3 -0
  175. package/dist/lab/run-lab-options.d.ts +12 -66
  176. package/dist/lab/run-lab-options.js +45 -275
  177. package/dist/lab/summary.d.ts +9 -4
  178. package/dist/lab/summary.js +15 -8
  179. package/dist/lab/types.d.ts +132 -132
  180. package/dist/lab/validation.d.ts +15 -15
  181. package/dist/lab/validation.js +28 -28
  182. package/dist/lab/warnings.js +20 -19
  183. package/dist/observer/artifact.d.ts +1 -1
  184. package/dist/observer/artifact.js +3 -3
  185. package/dist/observer/data.js +2 -2
  186. package/dist/observer/render.js +2 -2
  187. package/dist/observer/run-routes.d.ts +1 -1
  188. package/dist/observer/run-routes.js +5 -5
  189. package/dist/observer/serve.d.ts +17 -0
  190. package/dist/observer/serve.js +34 -3
  191. package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
  192. package/dist/routes/computer-use/bundle-parts.js +10 -3
  193. package/dist/routes/computer-use/bundle.d.ts +4 -11
  194. package/dist/routes/computer-use/bundle.js +9 -15
  195. package/dist/routes/computer-use/diagnostics.d.ts +1 -1
  196. package/dist/routes/computer-use/diagnostics.js +1 -1
  197. package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
  198. package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
  199. package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
  200. package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
  201. package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
  202. package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
  203. package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
  204. package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
  205. package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
  206. package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
  207. package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
  208. package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
  209. package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
  210. package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
  211. package/dist/routes/computer-use/external-comms.d.ts +4 -4
  212. package/dist/routes/computer-use/external-comms.js +19 -43
  213. package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
  214. package/dist/routes/computer-use/fanout-bundle.js +25 -29
  215. package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
  216. package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
  217. package/dist/routes/computer-use/in-process-desktop.js +3 -9
  218. package/dist/routes/computer-use/live-flush.d.ts +7 -5
  219. package/dist/routes/computer-use/live-flush.js +19 -27
  220. package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +12 -11
  221. package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
  222. package/dist/routes/computer-use/local-tree-pack.js +4 -5
  223. package/dist/routes/computer-use/local-vm.d.ts +11 -8
  224. package/dist/routes/computer-use/local-vm.js +39 -66
  225. package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
  226. package/dist/routes/computer-use/participant-desktop.js +5 -25
  227. package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
  228. package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
  229. package/dist/routes/computer-use/participant-facts.d.ts +7 -1
  230. package/dist/routes/computer-use/participant-facts.js +12 -1
  231. package/dist/routes/computer-use/participant-model.d.ts +19 -11
  232. package/dist/routes/computer-use/participant-model.js +49 -25
  233. package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
  234. package/dist/routes/computer-use/participant-prompt.js +4 -4
  235. package/dist/routes/computer-use/participant-runs.d.ts +6 -6
  236. package/dist/routes/computer-use/participant-runs.js +8 -8
  237. package/dist/routes/computer-use/plan.d.ts +21 -29
  238. package/dist/routes/computer-use/plan.js +52 -60
  239. package/dist/routes/computer-use/preflight.d.ts +3 -5
  240. package/dist/routes/computer-use/preflight.js +20 -16
  241. package/dist/routes/computer-use/rerun-selection.js +10 -6
  242. package/dist/routes/computer-use/result.d.ts +1 -1
  243. package/dist/routes/computer-use/result.js +40 -30
  244. package/dist/routes/computer-use/route.d.ts +3 -4
  245. package/dist/routes/computer-use/route.js +21 -19
  246. package/dist/routes/computer-use/self-report.d.ts +2 -2
  247. package/dist/routes/computer-use/self-report.js +4 -4
  248. package/dist/routes/computer-use/setup.d.ts +8 -14
  249. package/dist/routes/computer-use/setup.js +96 -72
  250. package/dist/routes/computer-use/single-bundle.d.ts +8 -11
  251. package/dist/routes/computer-use/single-bundle.js +20 -25
  252. package/dist/routes/computer-use/subject-projection.d.ts +5 -7
  253. package/dist/routes/computer-use/subject-projection.js +20 -19
  254. package/dist/routes/computer-use/types.d.ts +169 -210
  255. package/dist/routes/computer-use/types.js +13 -5
  256. package/dist/routes/preview.js +0 -1
  257. package/dist/routes/scripted/bundle.d.ts +3 -6
  258. package/dist/routes/scripted/bundle.js +11 -16
  259. package/dist/routes/scripted/plan.d.ts +5 -7
  260. package/dist/routes/scripted/plan.js +6 -4
  261. package/dist/routes/scripted/result.d.ts +4 -1
  262. package/dist/routes/scripted/result.js +10 -6
  263. package/dist/routes/scripted/route.js +10 -11
  264. package/dist/routes/scripted/scenario.d.ts +1 -1
  265. package/dist/routes/scripted/scenario.js +1 -1
  266. package/dist/routes/scripted/setup.d.ts +3 -2
  267. package/dist/routes/scripted/setup.js +22 -21
  268. package/dist/routes/scripted/subject.d.ts +8 -3
  269. package/dist/routes/scripted/subject.js +9 -5
  270. package/dist/routes/scripted/surface-records.js +1 -1
  271. package/dist/routes/scripted/surface-sessions.d.ts +2 -2
  272. package/dist/routes/scripted/surface-sessions.js +4 -4
  273. package/dist/routes/scripted/types.d.ts +19 -36
  274. package/dist/routes/scripted/types.js +1 -2
  275. package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
  276. package/dist/routes/shared-world/bundle.d.ts +2 -2
  277. package/dist/routes/shared-world/bundle.js +22 -26
  278. package/dist/routes/shared-world/checkpoints.d.ts +4 -4
  279. package/dist/routes/shared-world/checkpoints.js +4 -4
  280. package/dist/routes/shared-world/comms.d.ts +5 -4
  281. package/dist/routes/shared-world/comms.js +28 -41
  282. package/dist/routes/shared-world/external-public.d.ts +5 -5
  283. package/dist/routes/shared-world/external-public.js +19 -20
  284. package/dist/routes/shared-world/handoff.d.ts +4 -4
  285. package/dist/routes/shared-world/handoff.js +50 -50
  286. package/dist/routes/shared-world/lobby-code.d.ts +5 -5
  287. package/dist/routes/shared-world/lobby-code.js +13 -13
  288. package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
  289. package/dist/routes/shared-world/{seats.js → participant-specs.js} +43 -48
  290. package/dist/routes/shared-world/plan.d.ts +2 -6
  291. package/dist/routes/shared-world/plan.js +1 -2
  292. package/dist/routes/shared-world/provenance.d.ts +4 -4
  293. package/dist/routes/shared-world/provenance.js +4 -4
  294. package/dist/routes/shared-world/provisioned.d.ts +3 -2
  295. package/dist/routes/shared-world/provisioned.js +46 -40
  296. package/dist/routes/shared-world/result.js +31 -19
  297. package/dist/routes/shared-world/route.js +37 -41
  298. package/dist/routes/shared-world/setup.d.ts +5 -4
  299. package/dist/routes/shared-world/setup.js +12 -14
  300. package/dist/routes/shared-world/types.d.ts +53 -126
  301. package/dist/routes/shared-world/types.js +2 -2
  302. package/dist/routes/terminal/adapter.d.ts +8 -8
  303. package/dist/routes/terminal/adapter.js +28 -125
  304. package/dist/routes/terminal/bundle.d.ts +7 -12
  305. package/dist/routes/terminal/bundle.js +24 -34
  306. package/dist/routes/terminal/credentials.d.ts +2 -2
  307. package/dist/routes/terminal/credentials.js +16 -16
  308. package/dist/routes/terminal/dry-run.d.ts +1 -1
  309. package/dist/routes/terminal/dry-run.js +9 -11
  310. package/dist/routes/terminal/encoding.d.ts +1 -1
  311. package/dist/routes/terminal/encoding.js +2 -2
  312. package/dist/routes/terminal/ledger.d.ts +6 -6
  313. package/dist/routes/terminal/ledger.js +9 -9
  314. package/dist/routes/terminal/live-finish.d.ts +1 -2
  315. package/dist/routes/terminal/live-finish.js +21 -20
  316. package/dist/routes/terminal/live-sandbox.d.ts +3 -2
  317. package/dist/routes/terminal/live-sandbox.js +20 -20
  318. package/dist/routes/terminal/participant-text.d.ts +23 -0
  319. package/dist/routes/terminal/participant-text.js +165 -0
  320. package/dist/routes/terminal/plan.d.ts +2 -6
  321. package/dist/routes/terminal/plan.js +13 -9
  322. package/dist/routes/terminal/recorder.d.ts +6 -1
  323. package/dist/routes/terminal/recorder.js +12 -4
  324. package/dist/routes/terminal/result.js +4 -4
  325. package/dist/routes/terminal/route.js +26 -26
  326. package/dist/routes/terminal/runtime.d.ts +3 -2
  327. package/dist/routes/terminal/runtime.js +3 -3
  328. package/dist/routes/terminal/sandbox.d.ts +3 -3
  329. package/dist/routes/terminal/sandbox.js +9 -9
  330. package/dist/routes/terminal/session.js +16 -14
  331. package/dist/routes/terminal/token-usage.js +5 -5
  332. package/dist/routes/terminal/trace.d.ts +5 -8
  333. package/dist/routes/terminal/trace.js +9 -64
  334. package/dist/routes/terminal/types.d.ts +85 -93
  335. package/dist/routes/terminal/types.js +9 -4
  336. package/dist/run/active-runs.d.ts +13 -0
  337. package/dist/run/active-runs.js +12 -0
  338. package/dist/run/bundle-shape.d.ts +2 -1
  339. package/dist/run/bundle-shape.js +4 -4
  340. package/dist/run/bundle.d.ts +63 -56
  341. package/dist/run/bundle.js +9 -8
  342. package/dist/run/cost-summary.js +3 -2
  343. package/dist/run/costs.d.ts +6 -6
  344. package/dist/run/costs.js +10 -10
  345. package/dist/run/detail.d.ts +5 -5
  346. package/dist/run/detail.js +6 -6
  347. package/dist/run/dry-run.js +5 -12
  348. package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
  349. package/dist/run/{study-files.js → evidence-files.js} +5 -5
  350. package/dist/run/feedback-shape.js +1 -1
  351. package/dist/run/judge.d.ts +16 -4
  352. package/dist/run/judge.js +24 -7
  353. package/dist/run/locate.d.ts +2 -0
  354. package/dist/run/locate.js +3 -1
  355. package/dist/run/outcomes.d.ts +3 -3
  356. package/dist/run/outcomes.js +3 -3
  357. package/dist/run/participant-records.d.ts +2 -2
  358. package/dist/run/participant-records.js +2 -2
  359. package/dist/run/paths.js +1 -1
  360. package/dist/run/pricing.d.ts +19 -9
  361. package/dist/run/pricing.js +30 -18
  362. package/dist/run/projection.d.ts +13 -13
  363. package/dist/run/projection.js +8 -8
  364. package/dist/run/reclaim.d.ts +6 -0
  365. package/dist/run/reclaim.js +13 -3
  366. package/dist/run/results.d.ts +1 -1
  367. package/dist/run/run-index.d.ts +1 -1
  368. package/dist/run/run-index.js +11 -11
  369. package/dist/run/run.d.ts +4 -2
  370. package/dist/run/run.js +9 -5
  371. package/dist/run/sandbox-receipts.d.ts +4 -4
  372. package/dist/run/sandbox-receipts.js +4 -4
  373. package/dist/run/shared-world-evidence.d.ts +47 -47
  374. package/dist/run/shared-world-shape.d.ts +3 -3
  375. package/dist/run/shared-world-shape.js +11 -11
  376. package/dist/run/stats.d.ts +5 -5
  377. package/dist/run/stats.js +8 -8
  378. package/dist/run/status.d.ts +16 -6
  379. package/dist/run/status.js +31 -8
  380. package/dist/run/streams.d.ts +26 -19
  381. package/dist/run/terminal-contract.d.ts +5 -5
  382. package/dist/run/terminal-contract.js +4 -4
  383. package/dist/run/transient-comms-secrets.d.ts +5 -0
  384. package/dist/run/transient-comms-secrets.js +12 -0
  385. package/dist/run-lab.d.ts +36 -34
  386. package/dist/run-lab.js +41 -37
  387. package/dist/subject/desktop-cli.d.ts +1 -1
  388. package/dist/subject/desktop-cli.js +1 -1
  389. package/dist/subject/local-tree-archive.d.ts +1 -1
  390. package/dist/subject/local-tree-archive.js +4 -4
  391. package/dist/subject/local-tree.d.ts +2 -2
  392. package/dist/subject/local-tree.js +1 -1
  393. package/dist/subject/node-bootstrap.d.ts +1 -1
  394. package/dist/subject/node-bootstrap.js +4 -4
  395. package/dist/subject/runtime.js +5 -5
  396. package/dist/subject/serve.js +1 -1
  397. package/dist/subject/steps.d.ts +4 -4
  398. package/dist/subject/steps.js +5 -5
  399. package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
  400. package/dist/substrates/e2b/cdp-probe.js +1 -1
  401. package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
  402. package/dist/substrates/e2b/desktop-browser.js +4 -4
  403. package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
  404. package/dist/substrates/e2b/desktop-cdp.js +4 -4
  405. package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
  406. package/dist/substrates/e2b/desktop-geometry.js +3 -3
  407. package/dist/substrates/e2b/desktop-media.js +2 -2
  408. package/dist/substrates/e2b/sandbox.js +1 -1
  409. package/dist/substrates/e2b/sdk.js +2 -2
  410. package/dist/substrates/local/runtime-host.d.ts +2 -0
  411. package/dist/substrates/local/runtime-host.js +6 -0
  412. package/dist/tui/actions.d.ts +7 -5
  413. package/dist/tui/actions.js +18 -9
  414. package/dist/tui-app.js +42 -42
  415. package/dist/verify/actor.d.ts +10 -10
  416. package/dist/verify/actor.js +15 -15
  417. package/dist/verify/artifacts.d.ts +1 -1
  418. package/dist/verify/artifacts.js +3 -3
  419. package/dist/verify/costs.d.ts +2 -2
  420. package/dist/verify/costs.js +2 -2
  421. package/dist/verify/liveness.d.ts +1 -1
  422. package/dist/verify/liveness.js +4 -1
  423. package/dist/verify/rerun.d.ts +1 -1
  424. package/dist/verify/rerun.js +1 -1
  425. package/dist/verify/shared-world.js +2 -2
  426. package/dist/verify/verify.js +6 -6
  427. package/docs/README.md +1 -1
  428. package/docs/architecture/actor-contract.md +60 -22
  429. package/docs/architecture/desktop-sessions.md +9 -9
  430. package/docs/architecture/external-public-shared-world.md +5 -0
  431. package/docs/architecture/observer.md +4 -4
  432. package/docs/architecture/restricted-codex-analysis.md +36 -2
  433. package/docs/architecture/state-driven-executor.md +4 -5
  434. package/docs/architecture/task-protocol-support.md +3 -5
  435. package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
  436. package/docs/contracts/run-bundle.md +10 -8
  437. package/docs/contracts/schemas.md +109 -53
  438. package/docs/contracts/study-analysis.md +24 -0
  439. package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
  440. package/docs/product/automatic-analysis.md +1 -0
  441. package/docs/ramp/README.md +2 -1
  442. package/package.json +4 -4
  443. package/skills/humanish/SKILL.md +3 -2
  444. package/skills/humanish/agents/openai.yaml +1 -1
  445. package/dist/deprecated.d.ts +0 -90
  446. package/dist/deprecated.js +0 -106
  447. package/dist/lab/bag-overrides.d.ts +0 -18
  448. package/dist/lab/bag-overrides.js +0 -121
  449. package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
  450. package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
  451. /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
  452. /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
  453. /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
@@ -40,11 +40,11 @@ export interface LabExpectation {
40
40
  costUnknown: number;
41
41
  }
42
42
  /**
43
- * Derive what to expect from a lab's own history. Only FINISHED runs count: an interrupted run's
43
+ * Derive what to expect from a lab's own history. Only finished runs count: an interrupted run's
44
44
  * duration is the length of an accident, not of a study, and including it would quietly bias the
45
45
  * estimate the operator uses to decide whether to press Start.
46
46
  *
47
- * MODE MATTERS, and mixing modes is a lie rather than an imprecision. A dry run spends nothing and
47
+ * The mode matters: mixing modes produces a false figure. A dry run spends nothing and
48
48
  * takes no time, so a median over nine dry runs and one live one reports that a live run is free —
49
49
  * next to a control that spends money. Pass the mode the figure is about; omit it only for a
50
50
  * summary that is not attached to an action.
@@ -59,7 +59,7 @@ export declare function expectationLine(expectation: LabExpectation): string;
59
59
  /**
60
60
  * The one line a lab may say about itself, wherever it is shown.
61
61
  *
62
- * Prefers LIVE figures: cost and duration are what someone reads before spending, and a median
62
+ * Prefers live figures: cost and duration are what someone reads before spending, and a median
63
63
  * diluted by dry runs reports a live study as cheaper and faster than it has ever been. With no
64
64
  * live history it reports the count and claims nothing about time or money — which is why this is
65
65
  * shared rather than reimplemented per surface, since the two disagreeing is the whole failure.
@@ -104,15 +104,15 @@ export declare function livenessLabel(entry: Pick<RunIndexEntry, "liveness" | "v
104
104
  /** A lab as the labs list shows it: what is declared, joined to what actually happened. */
105
105
  export interface LabRow {
106
106
  /**
107
- * Stable identity for THIS ROW. A manifest's path when it has one, else the lab id — because two
107
+ * Stable identity for this row. A manifest's path when it has one, else the lab id, because two
108
108
  * manifests can declare the same id, and keying rows by id makes them collapse into a pair of
109
109
  * indistinguishable duplicates.
110
110
  */
111
111
  key: string;
112
- /** The declared id. Run history attributes to this, so it is NOT unique across manifests. */
112
+ /** The declared id. Run history attributes to this, so it is not unique across manifests. */
113
113
  labId: string;
114
114
  /**
115
- * The handle an operator would actually type. Lab resolution is by FILENAME, so the manifest
115
+ * The handle an operator would actually type. Lab resolution is by filename, so the manifest
116
116
  * `\`.humanish/labs/persona-contrast-live.yaml\`` is reached as `persona-contrast-live` even when
117
117
  * the id inside it says something else.
118
118
  */
@@ -120,25 +120,25 @@ export interface LabRow {
120
120
  /** The manifest's own title, when it has one. */
121
121
  title?: string;
122
122
  /**
123
- * The shortest label that is UNIQUE among the rows it is listed with: the title when no other
123
+ * The shortest label that is unique among the rows it is listed with: the title when no other
124
124
  * lab shares it, else the filename, else the full path. A list is only navigable if every row can
125
125
  * be told from every other one, and a title is not guaranteed to be distinct — two manifests in
126
- * this repo carry the same title AND the same declared id, differing only by filename.
126
+ * this repo carry the same title and the same declared id, differing only by filename.
127
127
  */
128
128
  label: string;
129
- /** The manifest's own words, for the list to say what this study IS. */
129
+ /** The manifest's own words, for the list to say what this study is. */
130
130
  description?: string;
131
131
  /** Repo-relative manifest path, absent for a lab known only from run history. */
132
132
  path?: string;
133
133
  origin?: "committed" | "ignored" | "explicit";
134
134
  /**
135
- * False for a lab that has runs but NO manifest here — renamed, deleted, or run from a path that
135
+ * False for a lab that has runs but no manifest here: renamed, deleted, or run from a path that
136
136
  * is gone. Its runs are still evidence and must stay reachable, so it is listed and marked rather
137
137
  * than dropped.
138
138
  */
139
139
  declared: boolean;
140
140
  /**
141
- * How many OTHER manifests declare this same lab id. Above zero, the run history below is shared
141
+ * How many other manifests declare this same lab id. Above zero, the run history below is shared
142
142
  * between them and cannot be attributed to one file — worth saying, because it is a
143
143
  * misconfiguration the operator almost certainly does not know about.
144
144
  */
@@ -169,13 +169,13 @@ export interface DeclaredLab {
169
169
  * deleted — that evidence still exists on disk, so dropping those rows would make real runs
170
170
  * unreachable from the surface that is supposed to list them.
171
171
  *
172
- * ONE ROW PER MANIFEST, not per id. The two are not the same thing: a manifest is addressed by its
172
+ * One row per manifest, not per id. The two are not the same thing: a manifest is addressed by its
173
173
  * filename while its runs attribute to the id declared inside it, so several files can legitimately
174
174
  * share an id. Collapsing them hides a real file; keying by id duplicates a row with no way to tell
175
175
  * the copies apart. Both happen in practice — this repo has exactly that pair.
176
176
  *
177
177
  * Order puts a lab someone is working in first, then labs by how recently they ran, then declared
178
- * labs that have never run (alphabetically BY WHAT IS DISPLAYED, so the order on screen is the
178
+ * labs that have never run (alphabetically by the displayed label, so the order on screen is the
179
179
  * order a reader can predict), then labs known only from history.
180
180
  */
181
181
  export declare function labRows(declared: readonly DeclaredLab[], entries: readonly RunIndexEntry[]): {
@@ -3,7 +3,7 @@
3
3
  // the parts most likely to be wrong are testable without a terminal.
4
4
  //
5
5
  // The honesty rules these encode, because they are the ones a UI is most tempted to break:
6
- // - a statistic ALWAYS carries its denominator, and says when it has none;
6
+ // - a statistic always carries its denominator, and says when it has none;
7
7
  // - an unknown cost is `null` (declared absent), never 0;
8
8
  // - truncation is reported, never silent;
9
9
  // - a participant's reported thinking is quoted, never paraphrased or summarized.
@@ -58,11 +58,11 @@ function recencyOf(entry) {
58
58
  return 0;
59
59
  }
60
60
  /**
61
- * Derive what to expect from a lab's own history. Only FINISHED runs count: an interrupted run's
61
+ * Derive what to expect from a lab's own history. Only finished runs count: an interrupted run's
62
62
  * duration is the length of an accident, not of a study, and including it would quietly bias the
63
63
  * estimate the operator uses to decide whether to press Start.
64
64
  *
65
- * MODE MATTERS, and mixing modes is a lie rather than an imprecision. A dry run spends nothing and
65
+ * The mode matters: mixing modes produces a false figure. A dry run spends nothing and
66
66
  * takes no time, so a median over nine dry runs and one live one reports that a live run is free —
67
67
  * next to a control that spends money. Pass the mode the figure is about; omit it only for a
68
68
  * summary that is not attached to an action.
@@ -78,7 +78,7 @@ export function expectationFor(entries, mode) {
78
78
  .map((entry) => entry.estimatedCostUsd)
79
79
  .filter((value) => typeof value === "number" && Number.isFinite(value))
80
80
  .sort((a, b) => a - b);
81
- // A cost is unknown whether it was DECLARED absent (`null`) or never recorded at all
81
+ // A cost is unknown whether it was declared absent (`null`) or never recorded at all
82
82
  // (`undefined` — every fail-closed exit finalized with no outcome). Counting only the first
83
83
  // reports "~$1.20 median · 3 runs" for a sample where two runs were never priced, which claims a
84
84
  // denominator the figure does not have.
@@ -134,7 +134,7 @@ export function expectationLine(expectation) {
134
134
  /**
135
135
  * The one line a lab may say about itself, wherever it is shown.
136
136
  *
137
- * Prefers LIVE figures: cost and duration are what someone reads before spending, and a median
137
+ * Prefers live figures: cost and duration are what someone reads before spending, and a median
138
138
  * diluted by dry runs reports a live study as cheaper and faster than it has ever been. With no
139
139
  * live history it reports the count and claims nothing about time or money — which is why this is
140
140
  * shared rather than reimplemented per surface, since the two disagreeing is the whole failure.
@@ -253,13 +253,13 @@ function labNameFromPath(manifestPath) {
253
253
  * deleted — that evidence still exists on disk, so dropping those rows would make real runs
254
254
  * unreachable from the surface that is supposed to list them.
255
255
  *
256
- * ONE ROW PER MANIFEST, not per id. The two are not the same thing: a manifest is addressed by its
256
+ * One row per manifest, not per id. The two are not the same thing: a manifest is addressed by its
257
257
  * filename while its runs attribute to the id declared inside it, so several files can legitimately
258
258
  * share an id. Collapsing them hides a real file; keying by id duplicates a row with no way to tell
259
259
  * the copies apart. Both happen in practice — this repo has exactly that pair.
260
260
  *
261
261
  * Order puts a lab someone is working in first, then labs by how recently they ran, then declared
262
- * labs that have never run (alphabetically BY WHAT IS DISPLAYED, so the order on screen is the
262
+ * labs that have never run (alphabetically by the displayed label, so the order on screen is the
263
263
  * order a reader can predict), then labs known only from history.
264
264
  */
265
265
  export function labRows(declared, entries) {
@@ -310,7 +310,7 @@ export function labRows(declared, entries) {
310
310
  .filter((lab) => !declaredIds.has(lab.labId))
311
311
  .map((lab) => build(lab.labId, undefined, false)),
312
312
  ];
313
- // Resolve each row's label BEFORE sorting, so the list is ordered by what a reader actually sees.
313
+ // Resolve each row's label before sorting, so the list is ordered by what a reader actually sees.
314
314
  assignLabels(rows);
315
315
  const label = (row) => row.label;
316
316
  rows.sort((left, right) => {
@@ -1,4 +1,5 @@
1
1
  import { type E2BDesktopModule } from "../substrates/e2b/sdk.js";
2
+ import { type PreparedRunArtifactPaths } from "./paths.js";
2
3
  declare const RECLAIM_RESULT_SCHEMA = "humanish.reclaim-result.v1";
3
4
  export declare const RECLAIM_RECEIPT_ARTIFACT = "reclaim-receipt.json";
4
5
  interface ReclaimOutcome {
@@ -31,6 +32,11 @@ export interface ReclaimHooks {
31
32
  requestTimeoutMs?: number;
32
33
  }
33
34
  export declare function reclaimRunSandboxes(cwd: string, runInput: string, hooks?: ReclaimHooks): Promise<ReclaimResult>;
35
+ /**
36
+ * Reclaim the run whose directory the caller already holds. Nothing is resolved, so an id that is
37
+ * also an alias (a run named `latest`) cannot reach another run's receipts.
38
+ */
39
+ export declare function reclaimPinnedRunSandboxes(cwd: string, runPaths: PreparedRunArtifactPaths, hooks?: ReclaimHooks): Promise<ReclaimResult>;
34
40
  /**
35
41
  * Kill the sandboxes left by interrupted `humanish lab preflight` probes. A probe journals under
36
42
  * .humanish/preflight/<probe-id>/ and removes the journal after a confirmed kill, so what is left
@@ -1,4 +1,4 @@
1
- // `humanish reclaim`: kill an interrupted run's sandboxes by the EXACT ids the run journaled at
1
+ // `humanish reclaim`: kill an interrupted run's sandboxes by the exact ids the run journaled at
2
2
  // create time (sandbox-receipts.ndjson), and report what happened to each. It reads one file inside
3
3
  // the managed run dir, kills by id, and never lists the account: an account-wide operation once
4
4
  // destroyed unrelated infrastructure. Without it, orphaned sandboxes run until the server-side
@@ -13,7 +13,17 @@ import { redactText, toErrorMessage } from "../evidence/redaction.js";
13
13
  import { runIdOf } from "./paths.js";
14
14
  const RECLAIM_RESULT_SCHEMA = "humanish.reclaim-result.v1";
15
15
  export const RECLAIM_RECEIPT_ARTIFACT = "reclaim-receipt.json";
16
- export async function reclaimRunSandboxes(cwd, runInput, hooks = {}) {
16
+ export function reclaimRunSandboxes(cwd, runInput, hooks = {}) {
17
+ return reclaimRun(cwd, runInput, () => resolveRunPath(cwd, runInput), hooks);
18
+ }
19
+ /**
20
+ * Reclaim the run whose directory the caller already holds. Nothing is resolved, so an id that is
21
+ * also an alias (a run named `latest`) cannot reach another run's receipts.
22
+ */
23
+ export function reclaimPinnedRunSandboxes(cwd, runPaths, hooks = {}) {
24
+ return reclaimRun(cwd, runIdOf(runPaths), () => Promise.resolve(runPaths), hooks);
25
+ }
26
+ async function reclaimRun(cwd, runInput, locate, hooks) {
17
27
  const warnings = [];
18
28
  const base = {
19
29
  schema: RECLAIM_RESULT_SCHEMA,
@@ -25,7 +35,7 @@ export async function reclaimRunSandboxes(cwd, runInput, hooks = {}) {
25
35
  };
26
36
  if (e2bDebugMode())
27
37
  return { ...base, ok: false, error: E2B_DEBUG_REFUSAL };
28
- const runPaths = await resolveRunPath(cwd, runInput);
38
+ const runPaths = await locate();
29
39
  if (!runPaths) {
30
40
  return {
31
41
  ...base,
@@ -30,7 +30,7 @@ export interface RunResult {
30
30
  observer?: ObserverResult;
31
31
  warnings: string[];
32
32
  error?: {
33
- code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_ANALYSIS_UNSUPPORTED" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_CONFLICT" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_LAB_COMMS_UNSUPPORTED" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED" | "HUMANISH_INVALID_CWD" | "HUMANISH_RUN_ID_IN_USE" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_INVALID_PORT" | "HUMANISH_UNSUPPORTED_RERUN_FLAGS" | "HUMANISH_WATCH_OPTION_CONFLICT" | "HUMANISH_WATCH_SAFE_NOT_APPLICABLE" | "HUMANISH_APP_URL_REMOVED" | "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
33
+ code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_ANALYSIS_UNSUPPORTED" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_LAB_COMMS_UNSUPPORTED" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED" | "HUMANISH_INVALID_CWD" | "HUMANISH_RUN_ID_IN_USE" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_INVALID_PORT" | "HUMANISH_UNSUPPORTED_RERUN_FLAGS" | "HUMANISH_WATCH_OPTION_CONFLICT" | "HUMANISH_WATCH_SAFE_NOT_APPLICABLE" | "HUMANISH_APP_URL_REMOVED" | "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
34
34
  message: string;
35
35
  };
36
36
  }
@@ -7,7 +7,7 @@ export interface RunIndexEntry {
7
7
  liveness: RunLiveness;
8
8
  mode?: "dry-run" | "live";
9
9
  /**
10
- * The pid that owns a run, when it recorded one. This is how a surface identifies the run IT just
10
+ * The pid that owns a run, when it recorded one. This is how a surface identifies the run it just
11
11
  * started without minting an id or guessing at a new directory: it spawned a process, and exactly
12
12
  * one run's record carries that pid.
13
13
  */
@@ -1,4 +1,4 @@
1
- // The run index (#455 PR 2): list and classify every run in a project WITHOUT parsing bundles.
1
+ // The run index (#455 PR 2): list and classify every run in a project without parsing bundles.
2
2
  //
3
3
  // The existing `listRuns` walks each run tree — screenshots included — validating symlinks and
4
4
  // then parses each `run.json`: measured 197ms cold / 152ms warm at 25 runs. That is fine for a
@@ -6,10 +6,10 @@
6
6
  // over SSH. This module reads the small `status.json` record each run now writes (586 bytes beside
7
7
  // a 92KB bundle) and caches per-run entries keyed on the stat of the file each was derived from.
8
8
  //
9
- // HONESTY RULES, unchanged from the record itself:
9
+ // Honesty rules, unchanged from the record itself:
10
10
  // - `run.json` is the evidence-of-record. Every field here is a projection for listing and
11
11
  // classification; nothing here is a claim about what a participant did.
12
- // - A run with no status record is NOT assumed finished. It is classified from what is on disk:
12
+ // - A run with no status record is not assumed finished. It is classified from what is on disk:
13
13
  // a bundle means finished, receipts without a bundle mean interrupted. That is the honest
14
14
  // reading of a run whose process died — and, before this contract existed, of every run.
15
15
  // - One unreadable run directory degrades that run, never the listing.
@@ -97,7 +97,7 @@ function usableStatusRecord(raw, runId) {
97
97
  return isRunStatusRecord(raw) && raw.runId === runId;
98
98
  }
99
99
  /**
100
- * The bundle-only reading, for a run with no usable status record. A bundle on disk USUALLY means
100
+ * The bundle-only reading, for a run with no usable status record. A bundle on disk usually means
101
101
  * the run reached its final write. But a live run now flushes an IN-PROGRESS bundle as it goes (so
102
102
  * anything asking what a participant is doing has something to read), and that bundle marks its
103
103
  * simulations `running`. With no status record there is no freshness to judge, and the honest
@@ -169,15 +169,15 @@ export async function readRunIndex(cwdInput, options = {}) {
169
169
  if (statusKey !== null) {
170
170
  const cached = cache?.get(runId, statusKey);
171
171
  if (cached !== undefined) {
172
- // Liveness is time-dependent, so it is recomputed even on a cache hit — a record that has
173
- // not changed can still have gone stale since the last read.
174
- runs.push(cached.derivedFrom === "status" && cached.updatedAt !== undefined
172
+ // A running record's liveness is time-dependent, so it is recomputed even on a cache hit:
173
+ // an unchanged record can still have gone stale. An ended record (finished or
174
+ // interrupted, both with completedAt) keeps the liveness it was cached with.
175
+ runs.push(cached.derivedFrom === "status" &&
176
+ cached.updatedAt !== undefined &&
177
+ cached.completedAt === undefined
175
178
  ? {
176
179
  ...cached,
177
- liveness: classifyRunStatus({
178
- state: cached.completedAt === undefined ? "running" : "finished",
179
- updatedAt: cached.updatedAt,
180
- }, nowMs),
180
+ liveness: classifyRunStatus({ state: "running", updatedAt: cached.updatedAt }, nowMs),
181
181
  }
182
182
  : cached);
183
183
  continue;
package/dist/run/run.d.ts CHANGED
@@ -13,7 +13,7 @@ interface StartRunOptions {
13
13
  lab?: RunLabProvenance | undefined;
14
14
  /** review.md for the published bundle. */
15
15
  renderReview: (bundle: RunBundle) => string;
16
- /** Used by `FinishedRun.renderObserver`; `render` is the routes' `renderObserverFn` seam. */
16
+ /** Used by `FinishedRun.renderObserver`; `render` is the `LabDeps.renderObserver` seam. */
17
17
  observer?: {
18
18
  open: boolean;
19
19
  render?: typeof renderObserver | undefined;
@@ -25,7 +25,9 @@ interface Run {
25
25
  readonly runId: string;
26
26
  readonly createdAt: string;
27
27
  readonly mode: "dry-run" | "live";
28
- /** Routes write their evidence files through these and hand them to lanes. */
28
+ /** The manifest the run came from (#455); bundleHead copies it into the bundle. */
29
+ readonly lab?: RunLabProvenance;
30
+ /** Routes write their evidence files through these and hand them to participants. */
29
31
  readonly paths: PreparedRunArtifactPaths;
30
32
  /**
31
33
  * Publish an in-progress bundle: run.json, review.json, review.md, events.ndjson and
package/dist/run/run.js CHANGED
@@ -7,6 +7,7 @@ import { renderObserver } from "../observer/render.js";
7
7
  import { RUN_BUNDLE_FILE, PUBLIC_TARGET_CWD } from "./bundle.js";
8
8
  import {} from "./results.js";
9
9
  import { createRunArtifactPaths, validatePreparedRunArtifactPaths, } from "./paths.js";
10
+ import { registerActiveRun } from "./active-runs.js";
10
11
  import { writeContainedOutputFile, writePreparedRunLatestPointer } from "./contained-output.js";
11
12
  import { beginRunStatus, runStatusOutcome, } from "./status.js";
12
13
  /** An entry point called in a state that does not admit it. */
@@ -66,6 +67,7 @@ export async function runScope(fn) {
66
67
  let closed = false;
67
68
  let started = false;
68
69
  let status;
70
+ let unregister;
69
71
  let finished;
70
72
  const admitted = new Set();
71
73
  const admit = (operation) => {
@@ -86,11 +88,11 @@ export async function runScope(fn) {
86
88
  const created = await createRunArtifactPaths(options.cwd, runId);
87
89
  if (!created.ok)
88
90
  return created;
89
- status = beginRunStatus(created.paths, {
90
- runId,
91
- mode: options.mode,
92
- ...(options.lab === undefined ? {} : { lab: options.lab }),
93
- });
91
+ // beginRunStatus reads only the mode and the lab provenance from the run's options.
92
+ status = beginRunStatus(created.paths, { ...options, runId });
93
+ // Registered before the first write lands: a signal while it is still settling reaches
94
+ // the handle, whose interrupt queues behind that write.
95
+ unregister = registerActiveRun({ cwd: options.cwd, runId, paths: created.paths, status });
94
96
  await status.started;
95
97
  return { ok: true, run: openRun(options, runId, created.paths, status) };
96
98
  })());
@@ -154,6 +156,7 @@ export async function runScope(fn) {
154
156
  runId,
155
157
  createdAt,
156
158
  mode: options.mode,
159
+ ...(options.lab === undefined ? {} : { lab: options.lab }),
157
160
  paths,
158
161
  writeSnapshot(bundle) {
159
162
  if (closed)
@@ -193,6 +196,7 @@ export async function runScope(fn) {
193
196
  finally {
194
197
  if (finished === undefined)
195
198
  await status?.finish();
199
+ unregister?.();
196
200
  }
197
201
  }
198
202
  return { result: outcome.result, finished };
@@ -4,7 +4,7 @@ export declare const SANDBOX_RECEIPTS_ARTIFACT = "sandbox-receipts.ndjson";
4
4
  export type SandboxProviderId = "e2b";
5
5
  export interface SandboxReceipt {
6
6
  at: string;
7
- /** The lane/role/subject label the sandbox belongs to (public-safe token). */
7
+ /** The participant or subject label the sandbox belongs to (public-safe token). */
8
8
  laneId: string;
9
9
  /** Who allocated the sandbox. Receipts written before this field existed have none. */
10
10
  provider?: SandboxProviderId;
@@ -21,10 +21,10 @@ export interface ParsedSandboxReceipt extends Omit<SandboxReceipt, "provider"> {
21
21
  provider: string;
22
22
  }
23
23
  /**
24
- * Append one receipt. Best-effort BY DESIGN: the receipt exists to protect the run, so a failed
25
- * receipt write must never fail the lane — the only cost of a miss is that `reclaim` cannot see
24
+ * Append one receipt. Best-effort by design: the receipt exists to protect the run, so a failed
25
+ * receipt write must never fail the participant — the only cost of a miss is that `reclaim` cannot see
26
26
  * this id and the TTL backstop covers it instead. Containment is the same prepare step every
27
- * artifact write uses; append (not atomic-replace) keeps racing lanes' receipts intact.
27
+ * artifact write uses; append (not atomic-replace) keeps racing participants' receipts intact.
28
28
  */
29
29
  export declare function appendSandboxReceipt(root: PreparedOutputRoot, receipt: SandboxReceipt): Promise<void>;
30
30
  /** Parse a receipts file leniently: a torn final line (crash mid-append) drops, valid lines keep. */
@@ -1,14 +1,14 @@
1
1
  // Every created sandbox id is journaled to the run dir the moment create returns, before any work
2
- // happens in it. The lane loop lives in the caller's local process, so a sleeping laptop, crash or
2
+ // happens in it. The participant loop lives in the caller's local process, so a sleeping laptop, crash or
3
3
  // kill loses every in-memory id; this append-only file keeps them for `humanish reclaim`.
4
4
  import { appendFile } from "node:fs/promises";
5
5
  import { prepareContainedOutputFile } from "./contained-output.js";
6
6
  export const SANDBOX_RECEIPTS_ARTIFACT = "sandbox-receipts.ndjson";
7
7
  /**
8
- * Append one receipt. Best-effort BY DESIGN: the receipt exists to protect the run, so a failed
9
- * receipt write must never fail the lane — the only cost of a miss is that `reclaim` cannot see
8
+ * Append one receipt. Best-effort by design: the receipt exists to protect the run, so a failed
9
+ * receipt write must never fail the participant — the only cost of a miss is that `reclaim` cannot see
10
10
  * this id and the TTL backstop covers it instead. Containment is the same prepare step every
11
- * artifact write uses; append (not atomic-replace) keeps racing lanes' receipts intact.
11
+ * artifact write uses; append (not atomic-replace) keeps racing participants' receipts intact.
12
12
  */
13
13
  export async function appendSandboxReceipt(root, receipt) {
14
14
  try {
@@ -1,58 +1,58 @@
1
1
  import type { ParticipantIds } from "./participant-records.js";
2
2
  export declare const SHARED_WORLD_SCHEMA = "humanish.shared-world.v1";
3
- /** The ONE shared service-plane provenance for a shared-world run (#164): single commit + a
4
- * seed-recipe digest + the provisioned env NAMES (values never). */
3
+ /** The shared service-plane provenance for a shared-world run (#164): single commit + a
4
+ * seed-recipe digest + the provisioned env names (never values). */
5
5
  export interface SharedWorldPlane {
6
6
  /** The cloned commit SHA of the shared plane (when the clone resolved one). */
7
7
  commit?: string;
8
- /** sha256-16 over the ordered seed-step command digests — the seeded-state RECIPE identity
8
+ /** sha256-16 over the ordered seed-step command digests: the seeded-state recipe identity
9
9
  * (not the runtime state). Pins "same seed recipe" across bundles. */
10
10
  seedDigest: string;
11
- /** Declared env NAMES provisioned for the shared plane (values never surface). */
11
+ /** Declared env names provisioned for the shared plane (values never surface). */
12
12
  envNames: string[];
13
13
  /**
14
- * CONCURRENT route only (#164 phase 2): sha256-16 of the harness-minted `getHost` URL's ORIGIN
15
- * (the first-class provisioned-subject target every actor drove — invariant 2). A DIGEST, not the
14
+ * Concurrent route only (#164 phase 2): sha256-16 of the harness-minted `getHost` URL's origin
15
+ * (the first-class provisioned-subject target every actor drove, per invariant 2). A digest replaces the
16
16
  * raw URL: a getHost URL embeds the (live) sandbox id and matches the publish-safety e2b-URL
17
17
  * redaction, so — like the stream URL and like sandbox ids — it never lands raw in a published
18
18
  * bundle (the raw tokenless URL is surfaced only on the ephemeral lab result). The orchestrator
19
- * confirms the URL is TOKENLESS (no authKey — invariant 1) before digesting. verify proves every
19
+ * confirms the URL is tokenless (no authKey, per invariant 1) before digesting. verify proves every
20
20
  * actor drove this host by digest equality. Absent on the sequential route.
21
21
  */
22
22
  hostDigest?: string;
23
23
  /**
24
- * CONCURRENT route only: the author's REQUIRED attestation that the subject behind the
25
- * internet-reachable getHost URL is synthetic seeded data (FIX-3). This is author-trust + a
26
- * provenance gate, NOT a no-real-data guarantee. Verify fails closed if absent on the concurrent route.
24
+ * Concurrent route only: the author's required attestation that the subject behind the
25
+ * internet-reachable getHost URL is synthetic seeded data. This is author-trust + a
26
+ * provenance gate; it does not guarantee the data is synthetic. Verify fails closed if absent on the concurrent route.
27
27
  *
28
- * FORBIDDEN on the external-public plane class: claiming synthetic on a real public site the
29
- * harness neither provisioned nor exposed would be a lie (verify asserts it ABSENT there).
28
+ * Forbidden on the external-public plane class: claiming synthetic on a real public site the
29
+ * harness neither provisioned nor exposed would be false (verify asserts it is absent there).
30
30
  */
31
31
  exposure?: "synthetic";
32
32
  /**
33
- * EXTERNAL-PUBLIC plane class only (#164 phase 2): sha256-16 of the OBSERVED origin the seats
34
- * CONVERGED on (the honest analog of hostDigest, but WEAKER and disclosed — the harness only
35
- * OBSERVES that each seat reached this origin; it never MINTED it). It is derived from what the
36
- * seats actually reached, NOT from the declared appUrl: verify proves every laneWindow.routeHostDigest
37
- * (that seat's CDP-observed final URL origin) equals it — inter-seat convergence on ONE OBSERVED
33
+ * External-public plane class only (#164 phase 2): sha256-16 of the observed origin the seats
34
+ * converged on. It is the counterpart of hostDigest with a weaker, disclosed claim: the harness only
35
+ * observes that each seat reached this origin and never minted it. It is derived from what the
36
+ * seats actually reached; the declared appUrl does not feed it. verify proves every laneWindow.routeHostDigest
37
+ * (that seat's CDP-observed final URL origin) equals it, which shows inter-seat convergence on one observed
38
38
  * origin, not harness control of the plane. A digest, not the raw origin (kept consistent with
39
39
  * hostDigest hygiene). Absent on getHost.
40
40
  */
41
41
  publicOriginDigest?: string;
42
42
  /**
43
43
  * EXTERNAL-PUBLIC plane class only: sha256-16 of the operator-DECLARED origin (from subject.appUrl),
44
- * recorded for reference/evidence ONLY. It is NEVER asserted equal to publicOriginDigest: a normal
45
- * cross-origin redirect (apex->www, http->https) makes the OBSERVED origin differ from the declared
46
- * one, which is expected. Operator OWNERSHIP rests on the subject.publicTarget.authorized attestation
47
- * + the declared appUrl, NOT on digest equality. A digest, not the raw origin. Absent on getHost.
44
+ * recorded for reference/evidence only. It is never asserted equal to publicOriginDigest: a normal
45
+ * cross-origin redirect (apex->www, http->https) makes the observed origin differ from the declared
46
+ * one, which is expected. Operator ownership rests on the subject.publicTarget.authorized attestation
47
+ * + the declared appUrl; digest equality plays no part. Only the digest is stored. Absent on getHost.
48
48
  */
49
49
  declaredOriginDigest?: string;
50
50
  }
51
51
  /**
52
- * CONCURRENT shape (#164 phase 2): one actor's harness-clocked activity window against the ONE
53
- * shared plane. OVERLAPPING windows mechanically prove ≥2 personas were active simultaneously.
54
- * `laneWindows` and `stateSeries` are INDEPENDENT series — there is deliberately NO per-delta→actor
55
- * field (causation under concurrency is structurally inexpressible — FIX-7).
52
+ * Concurrent shape (#164 phase 2): one actor's harness-clocked activity window against the one
53
+ * shared plane. Overlapping windows mechanically prove ≥2 personas were active simultaneously.
54
+ * `laneWindows` and `stateSeries` are independent series. There is deliberately no per-delta→actor
55
+ * field, because under concurrency the evidence cannot say which actor caused a state change.
56
56
  */
57
57
  export interface SharedWorldParticipantWindow {
58
58
  roleId: string;
@@ -63,13 +63,13 @@ export interface SharedWorldParticipantWindow {
63
63
  simId: string;
64
64
  /** Resolves to a real RunStream (the actor's trace) in this bundle. */
65
65
  streamId: string;
66
- /** ms on the ONE harness clock — the wrapped [start,end] the orchestrator MEASURED (FIX-1). */
66
+ /** ms on the one harness clock: the wrapped [start,end] the orchestrator measured. */
67
67
  startedAt: number;
68
68
  endedAt: number;
69
69
  /** The actor's terminal session verdict (per-persona). */
70
70
  verdict: string;
71
- /** sha256-16 of the ORIGIN of the getHost seat URL this actor drove. verify confirms it equals
72
- * plane.hostDigest — i.e. the actor drove EXACTLY the harness-minted host (invariant 2; FIX-2).
71
+ /** sha256-16 of the origin of the getHost seat URL this actor drove. verify confirms it equals
72
+ * plane.hostDigest, so the actor drove exactly the harness-minted host (invariant 2).
73
73
  * A digest, not the raw URL (a getHost URL is not publish-safe — see SharedWorldPlane.hostDigest). */
74
74
  routeHostDigest: string;
75
75
  /** The shared plane's commit this actor observed (omitted when unresolved). */
@@ -77,15 +77,15 @@ export interface SharedWorldParticipantWindow {
77
77
  /** The shared plane's seed-recipe digest this actor observed. */
78
78
  seedDigest: string;
79
79
  }
80
- /** CONCURRENT shape: one cadence checkpoint of the shared world under load. DIGEST-ONLY — the
81
- * allowed-keys tripwire (SHARED_WORLD_STATESERIES_KEYS) permits ONLY {timestamp, digest}. */
80
+ /** Concurrent shape: one cadence checkpoint of the shared world under load. Digest-only: the
81
+ * allowed-keys tripwire (SHARED_WORLD_STATESERIES_KEYS) permits only {timestamp, digest}. */
82
82
  export interface SharedWorldStateSnapshot {
83
- /** ms on the ONE harness clock. */
83
+ /** ms on the one harness clock. */
84
84
  timestamp: number;
85
85
  /** sha256-16 of the (scrubbed, redacted) combined probe output at this snapshot. */
86
86
  digest: string;
87
87
  }
88
- /** CONCURRENT shape: one persona's OUTCOME against the contended world (the "M of N" headline). */
88
+ /** Concurrent shape: one persona's outcome against the contended world (the "M of N" headline). */
89
89
  export interface SharedWorldOutcome {
90
90
  roleId: string;
91
91
  actorType?: string;
@@ -117,7 +117,7 @@ export interface SharedWorldCheckpoint {
117
117
  /** sha256-16 of the (scrubbed, redacted) combined probe output at this snapshot. */
118
118
  digest: string;
119
119
  /** True when this snapshot's digest differs from the previous checkpoint's — the observed
120
- * state changed across the intervening turn (delta attributed to the TURN, not an action). */
120
+ * state changed across the intervening turn (the delta is attributed to the whole turn). */
121
121
  deltaFromPrev: boolean;
122
122
  }
123
123
  /** A timeline turn: one role's seat session against the shared plane. Carries the plane
@@ -150,45 +150,45 @@ interface SharedWorldSkippedTail {
150
150
  estimatedTotalUsd?: number;
151
151
  }
152
152
  /**
153
- * The shared-world evidence block (`humanish.shared-world.v1`). TWO variants discriminated by
154
- * `topologyMode` (FIX-8 — renamed off `RunBundle.mode` to avoid the dry-run|live collision):
153
+ * The shared-world evidence block (`humanish.shared-world.v1`). Two variants discriminated by
154
+ * `topologyMode`, which is named so it does not collide with `RunBundle.mode` (dry-run|live):
155
155
  *
156
- * - SEQUENTIAL (`topologyMode: "sequential"`): `sequence` + an alternating `timeline`
156
+ * - Sequential (`topologyMode: "sequential"`): `sequence` + an alternating `timeline`
157
157
  * (cp-baseline → turn → cp → … → cp); limits `sequential-only` etc. No route writes it since
158
158
  * 0.106.0; verify still reads it so older bundles keep verifying.
159
- * - CONCURRENT (`topologyMode: "concurrent"`, #164 phase 2): `laneWindows` + `stateSeries` +
160
- * `outcomes`; limits `concurrent` etc. NO `timeline`.
159
+ * - Concurrent (`topologyMode: "concurrent"`, #164 phase 2): `laneWindows` + `stateSeries` +
160
+ * `outcomes`; limits `concurrent` etc. No `timeline`.
161
161
  *
162
162
  * Additive + optional on `humanish.run-bundle.v1` — absent on every non-shared-world bundle.
163
- * The mandatory `attributionLimits` are verify-enforced (FAIL CLOSED on a missing required or a
163
+ * The mandatory `attributionLimits` are verify-enforced (fail closed on a missing required or a
164
164
  * present forbidden limit).
165
165
  */
166
166
  export interface SharedWorldEvidence {
167
167
  schema: typeof SHARED_WORLD_SCHEMA;
168
168
  topology: "shared-world";
169
- /** The substrate discriminator (FIX-8). Branched on first by sharedWorldEvidenceFindings. */
169
+ /** The substrate discriminator. Branched on first by sharedWorldEvidenceFindings. */
170
170
  topologyMode: "sequential" | "concurrent";
171
171
  /**
172
- * CONCURRENT route only (#164 phase 2): the PLANE-class discriminator. Absent == the historical
172
+ * Concurrent route only (#164 phase 2): the plane-class discriminator. Absent == the historical
173
173
  * "provisioned-getHost" plane (a clone/local-tree subject served + getHost-exposed in-sandbox — the
174
- * harness MINTED the host; synthetic-seeded attestation + authoritative in-sandbox checkpoint
174
+ * harness minted the host; synthetic-seeded attestation + authoritative in-sandbox checkpoint
175
175
  * stateSeries). "external-public" == a real operator-owned public deployment used directly as the
176
- * plane (NO getHost/clone/seed; operator-attested, not harness-controlled; NO authoritative
176
+ * plane (no getHost/clone/seed; the operator attests it and the harness does not control it; no authoritative
177
177
  * shared-state proof — concurrency evidenced by temporal co-occupancy + observed lobby convergence).
178
- * verify gates EVERY getHost-specific assertion on this discriminator; existing bundles omit it and
178
+ * verify gates every getHost-specific assertion on this discriminator; existing bundles omit it and
179
179
  * default to provisioned-getHost, byte-stable.
180
180
  */
181
181
  planeClass?: "provisioned-getHost" | "external-public";
182
- /** The DECLARED number of role seats. */
182
+ /** The declared number of role seats. */
183
183
  roleCount: number;
184
184
  plane: SharedWorldPlane;
185
185
  /** The pinned, verify-enforced attribution ceiling (the set differs per topologyMode/planeClass). */
186
186
  attributionLimits: string[];
187
187
  /**
188
188
  * EXTERNAL-PUBLIC plane class only (#164 phase 2, optional-but-strong): sha256-16 of the shared
189
- * `/lobby/CODE` PATH every seat's CDP-observed URL converged on — the concrete "they were in ONE
189
+ * `/lobby/CODE` path every seat's CDP-observed URL converged on: the concrete "they were in one
190
190
  * shared world" proof, observation-derived and needing no subject change. Digest-only (the raw
191
- * 6-char CODE and full URLs are runtime-only and never land). Absent when seats did not converge.
191
+ * 6-char lobby code and full URLs are runtime-only and never land). Absent when seats did not converge.
192
192
  */
193
193
  lobbyConvergenceDigest?: string;
194
194
  /** The role ids that actually took a turn, in declared order. */
@@ -6,7 +6,7 @@ export declare const MANDATORY_ATTRIBUTION_LIMITS: readonly ["sequential-only",
6
6
  export declare const SHARED_WORLD_CHECKPOINT_KEYS: Set<string>;
7
7
  export declare const SHARED_WORLD_STATESERIES_KEYS: Set<string>;
8
8
  /**
9
- * Single-plane provenance: every item shares ONE (commit, seedDigest), and that pair matches
9
+ * Single-plane provenance: every item shares one (commit, seedDigest), and that pair matches
10
10
  * sharedWorld.plane. Only the first item that diverges from the plane is reported. The shape guard
11
11
  * has already typed both fields as strings (commit may be absent).
12
12
  */
@@ -18,8 +18,8 @@ export declare function planeProvenanceFindings(items: readonly Record<string, u
18
18
  /** Common shape findings shared by both topologyMode branches. */
19
19
  export declare function sharedWorldCommonFindings(bundle: RunBundle, sw: SharedWorldEvidence): string[];
20
20
  /**
21
- * Tolerant SHAPE guard for the shared-world evidence block (#164). Validates required fields +
22
- * types but TOLERATES extra keys (additive): the strict value-shape/timeline checks are
21
+ * Tolerant shape guard for the shared-world evidence block (#164). Validates required fields +
22
+ * types and tolerates extra keys (additive): the strict value-shape/timeline checks are
23
23
  * sharedWorldEvidenceFindings' job (an injected value-shaped checkpoint field must pass the shape
24
24
  * guard so verify can catch it fail-closed, not silently bounce off isRunBundle).
25
25
  */