humanish 0.108.0 → 0.109.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.
- package/ARCHITECTURE.md +58 -59
- package/CHANGELOG.md +13 -0
- package/CONTEXT.md +44 -44
- package/README.md +3 -3
- package/TELEMETRY.md +2 -2
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/restricted-participant.js +12 -12
- package/dist/actors/codex/restricted-session.d.ts +2 -2
- package/dist/actors/computer-use/actor.d.ts +6 -6
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +2 -2
- package/dist/actors/computer-use/admission-limit.js +3 -3
- package/dist/actors/computer-use/executor-error.d.ts +2 -2
- package/dist/actors/computer-use/executor-error.js +3 -3
- package/dist/actors/computer-use/loop/actions.js +5 -5
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +1 -1
- package/dist/actors/computer-use/loop/ending.js +12 -11
- package/dist/actors/computer-use/loop/observation.js +6 -5
- package/dist/actors/computer-use/loop/provider-call.js +11 -11
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +2 -2
- package/dist/actors/computer-use/loop/trace.js +3 -2
- package/dist/actors/computer-use/loop/types.d.ts +24 -24
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop.d.ts +6 -1
- package/dist/actors/computer-use/loop.js +26 -4
- package/dist/actors/computer-use/openai-provider.d.ts +2 -2
- package/dist/actors/computer-use/openai-provider.js +8 -8
- package/dist/actors/computer-use/provider-error.d.ts +4 -4
- package/dist/actors/computer-use/provider-error.js +6 -6
- package/dist/actors/contract.d.ts +4 -4
- package/dist/actors/contract.js +1 -1
- package/dist/actors/local-agent/claude-session.js +3 -3
- package/dist/actors/local-agent/cli.d.ts +1 -1
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/reasoning-effort.js +3 -3
- package/dist/actors/registry.d.ts +2 -2
- package/dist/actors/registry.js +3 -3
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/actor.js +1 -1
- package/dist/analysis/automatic-completion.d.ts +7 -7
- package/dist/analysis/automatic-completion.js +1 -1
- package/dist/analysis/automatic-config.d.ts +6 -6
- package/dist/analysis/automatic-config.js +1 -1
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/types.d.ts +6 -0
- package/dist/browser-control/client.js +16 -16
- package/dist/browser-control/dispatcher.js +4 -4
- package/dist/browser-control/protocol.js +14 -14
- package/dist/browser-control/recording-transfer.js +4 -4
- package/dist/browser-control/transport.js +7 -7
- package/dist/cli/commands/analysis-signals.d.ts +2 -2
- package/dist/cli/commands/comms.js +14 -22
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +0 -15
- package/dist/cli/commands/run-command.d.ts +2 -2
- package/dist/cli/commands/run-command.js +3 -3
- package/dist/cli/commands/runs.js +3 -5
- package/dist/cli/commands/setup.js +5 -7
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +5 -5
- package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
- package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +12 -12
- package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
- package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
- package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
- package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +3 -3
- package/dist/cli/commands/study-route-run.d.ts +19 -0
- package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
- package/dist/cli/commands/study-route-scripted.d.ts +17 -0
- package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
- package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
- package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +7 -7
- package/dist/cli/commands/study-route-terminal.d.ts +17 -0
- package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
- package/dist/cli/commands/study-run.d.ts +9 -0
- package/dist/cli/commands/{lab-run.js → study-run.js} +34 -34
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +5 -5
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +1 -1
- package/dist/cli/commands/study.js +13 -49
- package/dist/cli/commands/tui.js +12 -12
- package/dist/cli/commands/watch.js +30 -65
- package/dist/cli/deprecations.d.ts +1 -13
- package/dist/cli/deprecations.js +0 -30
- package/dist/cli/doctor.d.ts +3 -3
- package/dist/cli/doctor.js +16 -16
- package/dist/cli/first-run-path.d.ts +4 -4
- package/dist/cli/first-run-path.js +7 -7
- package/dist/cli/io.d.ts +3 -3
- package/dist/cli/io.js +2 -2
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +2 -2
- package/dist/cli/orientation.d.ts +4 -4
- package/dist/cli/orientation.js +58 -20
- package/dist/cli/program.js +3 -4
- package/dist/cli/telemetry.d.ts +1 -1
- package/dist/cli/telemetry.js +14 -20
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/catch-host.js +3 -3
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +4 -3
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch.d.ts +2 -2
- package/dist/comms/sandbox-catch.js +2 -2
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +29 -32
- package/dist/feedback/draft.js +2 -2
- package/dist/feedback/export.js +3 -2
- package/dist/feedback/proof.d.ts +1 -1
- package/dist/feedback/proof.js +2 -2
- package/dist/guest/bootstrap.js +6 -6
- package/dist/guest/browser-tools.js +8 -8
- package/dist/guest/chromium-text.js +17 -17
- package/dist/guest/desktop-executor.d.ts +2 -2
- package/dist/guest/desktop-executor.js +20 -20
- package/dist/guest/desktop-keys.js +4 -4
- package/dist/guest/desktop-media.d.ts +2 -2
- package/dist/guest/desktop-media.js +16 -16
- package/dist/guest/desktop-native.js +10 -10
- package/dist/guest/runtime-desktop.js +2 -2
- package/dist/guest/runtime-processes.d.ts +2 -2
- package/dist/guest/runtime-processes.js +2 -2
- package/dist/guest/runtime.js +5 -5
- package/dist/index.d.ts +13 -15
- package/dist/index.js +6 -8
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +1 -1
- package/dist/observer/data.d.ts +1 -1
- package/dist/observer/library.d.ts +2 -0
- package/dist/observer/library.js +4 -1
- package/dist/observer/render.js +7 -1
- package/dist/observer/run-routes.d.ts +1 -0
- package/dist/observer/run-routes.js +37 -12
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer-app.html +1 -1
- package/dist/routes/computer-use/bundle-parts.js +3 -2
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +7 -6
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +5 -5
- package/dist/routes/computer-use/e2b-desktop/comms.js +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/start.js +3 -4
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -3
- package/dist/routes/computer-use/external-comms.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +11 -10
- package/dist/routes/computer-use/fanout-records.js +2 -2
- package/dist/routes/computer-use/live-flush.d.ts +3 -3
- package/dist/routes/computer-use/live-phase.d.ts +2 -3
- package/dist/routes/computer-use/live-phase.js +3 -3
- package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
- package/dist/routes/computer-use/local-tree-pack.js +1 -1
- package/dist/routes/computer-use/local-vm.d.ts +8 -8
- package/dist/routes/computer-use/local-vm.js +2 -2
- package/dist/routes/computer-use/participant-desktop.d.ts +3 -3
- package/dist/routes/computer-use/participant-desktop.js +1 -1
- package/dist/routes/computer-use/participant-execution.js +1 -1
- package/dist/routes/computer-use/participant-model.js +3 -3
- package/dist/routes/computer-use/participant-prompt.d.ts +5 -5
- package/dist/routes/computer-use/participant-prompt.js +3 -3
- package/dist/routes/computer-use/participant-runs.d.ts +10 -10
- package/dist/routes/computer-use/participant-runs.js +14 -13
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +24 -24
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +5 -5
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +3 -2
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +13 -12
- package/dist/routes/computer-use/route.d.ts +12 -12
- package/dist/routes/computer-use/route.js +19 -19
- package/dist/routes/computer-use/self-report.js +1 -1
- package/dist/routes/computer-use/setup.d.ts +22 -22
- package/dist/routes/computer-use/setup.js +15 -15
- package/dist/routes/computer-use/single-bundle.d.ts +4 -4
- package/dist/routes/computer-use/single-bundle.js +14 -13
- package/dist/routes/computer-use/subject-projection.d.ts +3 -3
- package/dist/routes/computer-use/types.d.ts +34 -34
- package/dist/routes/computer-use/types.js +3 -3
- package/dist/routes/preview.d.ts +6 -6
- package/dist/routes/preview.js +5 -5
- package/dist/routes/scripted/bundle.d.ts +6 -6
- package/dist/routes/scripted/bundle.js +10 -9
- package/dist/routes/scripted/plan.d.ts +7 -7
- package/dist/routes/scripted/plan.js +6 -6
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +9 -9
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +11 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +3 -3
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +4 -4
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +3 -3
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +2 -2
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +17 -17
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +3 -3
- package/dist/routes/shared-world/bundle.js +15 -14
- package/dist/routes/shared-world/checkpoints.d.ts +3 -3
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +9 -9
- package/dist/routes/shared-world/comms.js +6 -5
- package/dist/routes/shared-world/participant-specs.d.ts +3 -3
- package/dist/routes/shared-world/participant-specs.js +7 -7
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +9 -9
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +4 -4
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +11 -10
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +19 -19
- package/dist/routes/shared-world/setup.d.ts +13 -13
- package/dist/routes/shared-world/setup.js +19 -19
- package/dist/routes/shared-world/types.d.ts +27 -27
- package/dist/routes/terminal/adapter.d.ts +2 -2
- package/dist/routes/terminal/adapter.js +4 -4
- package/dist/routes/terminal/bundle.d.ts +11 -11
- package/dist/routes/terminal/bundle.js +12 -12
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +5 -5
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +9 -9
- package/dist/routes/terminal/ledger.d.ts +2 -2
- package/dist/routes/terminal/lifetime.d.ts +1 -1
- package/dist/routes/terminal/lifetime.js +1 -1
- package/dist/routes/terminal/live-finish.d.ts +2 -2
- package/dist/routes/terminal/live-finish.js +7 -7
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +3 -2
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +2 -2
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +5 -5
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +7 -7
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +14 -14
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +7 -7
- package/dist/routes/terminal/trace.d.ts +2 -2
- package/dist/routes/terminal/types.d.ts +24 -24
- package/dist/routes/terminal/types.js +2 -2
- package/dist/run/bundle.d.ts +7 -7
- package/dist/run/bundle.js +2 -2
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +72 -43
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +2 -2
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.js +2 -2
- package/dist/run/projection.d.ts +32 -32
- package/dist/run/projection.js +44 -44
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +1 -1
- package/dist/run/results.d.ts +2 -2
- package/dist/run/run-cost.d.ts +53 -0
- package/dist/run/run-cost.js +105 -0
- package/dist/run/run-index-analysis.d.ts +15 -0
- package/dist/run/run-index-analysis.js +77 -0
- package/dist/run/run-index.d.ts +11 -1
- package/dist/run/run-index.js +63 -49
- package/dist/run/run.d.ts +3 -3
- package/dist/run/run.js +2 -2
- package/dist/run/shared-world-evidence.d.ts +1 -1
- package/dist/run/shared-world-shape.js +1 -1
- package/dist/run/stats.d.ts +3 -3
- package/dist/run/stats.js +14 -14
- package/dist/run/status.d.ts +10 -2
- package/dist/run/status.js +6 -3
- package/dist/run/streams.d.ts +2 -2
- package/dist/run/study-provenance.d.ts +4 -2
- package/dist/run/study-provenance.js +7 -4
- package/dist/run/study-result.d.ts +0 -5
- package/dist/run/study-result.js +1 -1
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -45
- package/dist/{lab → study}/adapter-extension.d.ts +8 -20
- package/dist/{lab → study}/adapter-extension.js +2 -14
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +10 -10
- package/dist/{lab → study}/adapter-scorer-loader.js +3 -3
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +12 -12
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +37 -20
- package/dist/study/convert.d.ts +1 -1
- package/dist/study/convert.js +15 -15
- package/dist/{lab → study}/device-presets.d.ts +2 -2
- package/dist/{lab → study}/discover.d.ts +29 -23
- package/dist/{lab → study}/discover.js +97 -118
- package/dist/{lab → study}/doctor.d.ts +11 -11
- package/dist/{lab → study}/doctor.js +18 -18
- package/dist/study/files.d.ts +2 -2
- package/dist/study/files.js +6 -5
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/{lab → study}/init-templates.js +16 -11
- package/dist/{lab → study}/init.d.ts +1 -1
- package/dist/{lab → study}/init.js +7 -4
- package/dist/{lab → study}/keys.d.ts +2 -2
- package/dist/{lab → study}/keys.js +10 -10
- package/dist/study/migrate.d.ts +1 -1
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +5 -5
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/study-v3.d.ts +3 -5
- package/dist/{lab → study}/parse/study-v3.js +3 -3
- package/dist/{lab → study}/parse/subject-state.d.ts +8 -8
- package/dist/{lab → study}/parse/subject-state.js +4 -4
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +8 -8
- package/dist/{lab → study}/parse/values.d.ts +2 -2
- package/dist/{lab → study}/persona-resolve.d.ts +4 -4
- package/dist/{lab → study}/persona-resolve.js +2 -2
- package/dist/{lab → study}/plan-base.d.ts +7 -7
- package/dist/{lab → study}/plan-base.js +1 -1
- package/dist/{lab → study}/plan-participants.d.ts +10 -10
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +28 -28
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/{lab → study}/plan.js +20 -20
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +9 -8
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +3 -3
- package/dist/{lab → study}/preflight.d.ts +31 -31
- package/dist/{lab → study}/preflight.js +8 -8
- package/dist/{lab → study}/requirements.d.ts +3 -3
- package/dist/{lab → study}/requirements.js +1 -1
- package/dist/study/route-inputs.d.ts +28 -0
- package/dist/{lab → study}/route-inputs.js +1 -1
- package/dist/{lab → study}/routing.d.ts +12 -12
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -10
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -3
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +8 -17
- package/dist/study/run-study-homes.js +3 -0
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +13 -12
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +2 -2
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +10 -10
- package/dist/{lab → study}/summary.js +15 -15
- package/dist/{lab → study}/tasks.d.ts +3 -3
- package/dist/{lab → study}/tasks.js +1 -1
- package/dist/{lab → study}/types.d.ts +104 -104
- package/dist/{lab → study}/types.js +1 -1
- package/dist/{lab → study}/validation.d.ts +19 -19
- package/dist/{lab → study}/validation.js +13 -13
- package/dist/{lab → study}/warnings.d.ts +4 -4
- package/dist/{lab → study}/warnings.js +1 -1
- package/dist/subject/clone.d.ts +6 -6
- package/dist/subject/clone.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +3 -3
- package/dist/subject/local-tree.d.ts +3 -3
- package/dist/subject/runtime.js +2 -2
- package/dist/subject/serve.d.ts +4 -4
- package/dist/subject/state.d.ts +3 -3
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +1 -1
- package/dist/subject/steps.js +1 -1
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +4 -4
- package/dist/substrates/e2b/desktop-browser.js +1 -1
- package/dist/substrates/e2b/desktop-cdp.d.ts +1 -1
- package/dist/substrates/e2b/desktop-cdp.js +1 -1
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +12 -12
- package/dist/substrates/e2b/desktop-geometry.d.ts +1 -1
- package/dist/substrates/e2b/desktop-geometry.js +1 -1
- package/dist/substrates/e2b/desktop-media.d.ts +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +3 -3
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +1 -1
- package/dist/substrates/e2b/sdk.js +1 -1
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/contract.d.ts +8 -8
- package/dist/tui/contract.js +2 -2
- package/dist/tui/launch.d.ts +3 -3
- package/dist/tui/launch.js +22 -16
- package/dist/tui-app.js +139 -139
- package/dist/verify/subject.d.ts +1 -1
- package/dist/verify/subject.js +1 -1
- package/dist/verify/verify.js +2 -1
- package/docs/architecture/actor-contract.md +5 -5
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/external-public-shared-world.md +8 -7
- package/docs/architecture/github-feedback-loop.md +1 -1
- package/docs/architecture/task-protocol-support.md +1 -1
- package/docs/architecture/terminal-product-route.md +18 -18
- package/docs/contracts/adapter-fixtures.md +2 -2
- package/docs/contracts/errors.md +8 -8
- package/docs/contracts/run-bundle.md +1 -4
- package/docs/contracts/schemas.md +61 -42
- package/docs/contracts/study-analysis.md +4 -1
- package/docs/contracts/study-costs.md +17 -2
- package/examples/README.md +1 -1
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +1 -1
- package/skills/humanish/SKILL.md +8 -6
- package/skills/humanish/agents/openai.yaml +1 -1
- package/dist/cli/commands/lab-format.d.ts +0 -9
- package/dist/cli/commands/lab-route-run.d.ts +0 -19
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
- package/dist/cli/commands/lab-run.d.ts +0 -9
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/deprecated-fields.d.ts +0 -10
- package/dist/lab/deprecated-fields.js +0 -24
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/plan.d.ts +0 -13
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -8
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-homes.js +0 -7
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/library-aliases.d.ts +0 -56
- package/dist/library-aliases.js +0 -22
- package/dist/run-lab.d.ts +0 -112
- /package/dist/{lab → study}/device-presets.js +0 -0
- /package/dist/{lab → study}/init-paths.d.ts +0 -0
- /package/dist/{lab → study}/init-paths.js +0 -0
- /package/dist/{lab → study}/init-plan.d.ts +0 -0
- /package/dist/{lab → study}/init-plan.js +0 -0
- /package/dist/{lab → study}/parse/comms.js +0 -0
- /package/dist/{lab → study}/parse/execution.js +0 -0
- /package/dist/{lab → study}/parse/values.js +0 -0
- /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
- /package/dist/{lab → study}/participant-assignment.js +0 -0
- /package/dist/{lab → study}/persona.d.ts +0 -0
- /package/dist/{lab → study}/persona.js +0 -0
- /package/dist/{lab → study}/routing.js +0 -0
package/dist/run/status.d.ts
CHANGED
|
@@ -32,6 +32,11 @@ interface RunStatusOutcome {
|
|
|
32
32
|
};
|
|
33
33
|
/** The run-level estimate, `null` when declared absent (never coerced to 0). */
|
|
34
34
|
estimatedCostUsd?: number | null;
|
|
35
|
+
/**
|
|
36
|
+
* `cost.fullyEstimated`: false when some participant or desktop usage has no price, so the
|
|
37
|
+
* estimate is a lower bound. Absent means unknown, as in every record written before 0.109.
|
|
38
|
+
*/
|
|
39
|
+
estimatedCostComplete?: boolean;
|
|
35
40
|
durationMs?: number;
|
|
36
41
|
}
|
|
37
42
|
/** The outcome a finalized status record carries, read from the bundle that was just written. */
|
|
@@ -43,7 +48,10 @@ export interface RunStatusRecord {
|
|
|
43
48
|
mode: "dry-run" | "live";
|
|
44
49
|
/** Absent when the run did not come from a study file (a library caller, a bare `run`). */
|
|
45
50
|
study?: RunStudyProvenance;
|
|
46
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* `study`'s value, as runs saved by 0.108 and earlier wrote it. humanish no longer writes it.
|
|
53
|
+
* Read either through studyProvenanceOf.
|
|
54
|
+
*/
|
|
47
55
|
lab?: RunStudyProvenance;
|
|
48
56
|
/** The pid that owns the run, for local liveness checks. */
|
|
49
57
|
pid: number;
|
|
@@ -79,7 +87,7 @@ export interface RunStatusHandle {
|
|
|
79
87
|
export interface BeginRunStatusOptions {
|
|
80
88
|
runId: string;
|
|
81
89
|
mode: "dry-run" | "live";
|
|
82
|
-
|
|
90
|
+
study?: RunStudyProvenance | undefined;
|
|
83
91
|
}
|
|
84
92
|
/**
|
|
85
93
|
* Start a run's status record and keep it fresh. Fire-and-forget by design: a status write that
|
package/dist/run/status.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// Run identity and liveness on disk: one small record per run, written by every backend, that says
|
|
2
|
-
// which
|
|
2
|
+
// which study the run belongs to and whether it is still alive. A reader can list and classify runs
|
|
3
3
|
// from it without parsing every bundle, and can tell a live run from an abandoned one.
|
|
4
4
|
//
|
|
5
5
|
// run.json remains the evidence of record. This file is a derived index and liveness record:
|
|
6
6
|
// `verify` never gates on it, nothing here is a claim about what a participant did, and when the
|
|
7
7
|
// two disagree run.json wins and this file can be rebuilt from it.
|
|
8
8
|
//
|
|
9
|
-
// Public safety: it holds only the run id, the
|
|
9
|
+
// Public safety: it holds only the run id, the study id/path/origin (the strings `humanish study list`
|
|
10
10
|
// prints), the mode, a local pid and timestamps. It holds no hostname or user/path identity: an
|
|
11
11
|
// operator may share the run directory, so a share-safety gate must have nothing to strip here.
|
|
12
12
|
import { isProvenanceField, studyFields } from "./study-provenance.js";
|
|
@@ -42,6 +42,9 @@ export function runStatusOutcome(bundle) {
|
|
|
42
42
|
...(bundle.cost?.estimatedTotalUsd === undefined
|
|
43
43
|
? {}
|
|
44
44
|
: { estimatedCostUsd: bundle.cost.estimatedTotalUsd }),
|
|
45
|
+
...(typeof bundle.cost?.fullyEstimated === "boolean"
|
|
46
|
+
? { estimatedCostComplete: bundle.cost.fullyEstimated }
|
|
47
|
+
: {}),
|
|
45
48
|
};
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
@@ -57,7 +60,7 @@ export function beginRunStatus(runPaths, options) {
|
|
|
57
60
|
runId: options.runId,
|
|
58
61
|
state: "running",
|
|
59
62
|
mode: options.mode,
|
|
60
|
-
...studyFields(options.
|
|
63
|
+
...studyFields(options.study),
|
|
61
64
|
pid: process.pid,
|
|
62
65
|
startedAt,
|
|
63
66
|
updatedAt: startedAt,
|
package/dist/run/streams.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface RunDesktopGeometry {
|
|
|
64
64
|
source: "xdpyinfo";
|
|
65
65
|
};
|
|
66
66
|
/**
|
|
67
|
-
* The device preset as declared by the
|
|
67
|
+
* The device preset as declared by the study, present only when it differs from `requested`
|
|
68
68
|
* because the rendered width was floored to MIN_DESKTOP_RENDER_WIDTH.
|
|
69
69
|
*
|
|
70
70
|
* Without this, a floored run is indistinguishable from a faithful one: `verified` compares
|
|
@@ -96,7 +96,7 @@ export interface RunDesktopGeometry {
|
|
|
96
96
|
source: "cdp";
|
|
97
97
|
};
|
|
98
98
|
/**
|
|
99
|
-
* Mobile fidelity beyond viewport size, present only when the
|
|
99
|
+
* Mobile fidelity beyond viewport size, present only when the study asked for it. `requested`
|
|
100
100
|
* is what was applied through CDP; `resolved` is what the page reported about itself afterwards
|
|
101
101
|
* and is the proof, never copied from the request. A run without this block is a
|
|
102
102
|
* responsive-viewport study, whatever its preset is named.
|
|
@@ -26,10 +26,12 @@ export declare function studyProvenanceOf(record: {
|
|
|
26
26
|
source?: unknown;
|
|
27
27
|
};
|
|
28
28
|
}): RunStudyProvenance | undefined;
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* `study`, as run.json and status.json write it. 0.108 wrote `lab` beside it with the same value;
|
|
31
|
+
* 0.109 stopped, and studyProvenanceOf still reads `lab` from those runs.
|
|
32
|
+
*/
|
|
30
33
|
export declare function studyFields(study: RunStudyProvenance | undefined): {
|
|
31
34
|
study?: RunStudyProvenance;
|
|
32
|
-
lab?: RunStudyProvenance;
|
|
33
35
|
};
|
|
34
36
|
/**
|
|
35
37
|
* The study id a run names by the `study:<id>` or `lab:<id>` convention on its persona or scenario
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Which study a saved run came from. run.json and status.json write it as `study
|
|
2
|
-
// with the same value
|
|
1
|
+
// Which study a saved run came from. run.json and status.json write it as `study`; runs saved by
|
|
2
|
+
// 0.108 and earlier also carry `lab` with the same value. Every reader goes through
|
|
3
3
|
// studyProvenanceOf, which also reads a run older than both fields by the `study:<id>` or
|
|
4
4
|
// `lab:<id>` convention on its persona and scenario sources.
|
|
5
5
|
const ORIGINS = ["committed", "ignored", "explicit"];
|
|
@@ -38,9 +38,12 @@ export function studyProvenanceOf(record) {
|
|
|
38
38
|
const id = inferLegacyStudyId(record);
|
|
39
39
|
return id === undefined ? undefined : { id };
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* `study`, as run.json and status.json write it. 0.108 wrote `lab` beside it with the same value;
|
|
43
|
+
* 0.109 stopped, and studyProvenanceOf still reads `lab` from those runs.
|
|
44
|
+
*/
|
|
42
45
|
export function studyFields(study) {
|
|
43
|
-
return study === undefined ? {} : { study
|
|
46
|
+
return study === undefined ? {} : { study };
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
46
49
|
* The study id a run names by the `study:<id>` or `lab:<id>` convention on its persona or scenario
|
|
@@ -6,11 +6,6 @@ export interface StudyResultIdentity<R extends string> {
|
|
|
6
6
|
route: R;
|
|
7
7
|
/** The study's `id`. */
|
|
8
8
|
studyId: string;
|
|
9
|
-
/**
|
|
10
|
-
* The study's `id`, the same value as `studyId`.
|
|
11
|
-
* @deprecated Read `studyId`. The next minor removes it.
|
|
12
|
-
*/
|
|
13
|
-
labId: string;
|
|
14
9
|
}
|
|
15
10
|
/** The identity fields for a result of route `route` from the study `studyId`. */
|
|
16
11
|
export declare function studyResultIdentity<R extends string>(route: R, studyId: string): StudyResultIdentity<R>;
|
package/dist/run/study-result.js
CHANGED
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
export const STUDY_RESULT_SCHEMA = "humanish.study-result.v1";
|
|
6
6
|
/** The identity fields for a result of route `route` from the study `studyId`. */
|
|
7
7
|
export function studyResultIdentity(route, studyId) {
|
|
8
|
-
return { schema: STUDY_RESULT_SCHEMA, route, studyId
|
|
8
|
+
return { schema: STUDY_RESULT_SCHEMA, route, studyId };
|
|
9
9
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { LocalVmInput } from "./routes/computer-use/types.js";
|
|
2
|
+
import { type LateScorer } from "./study/route-inputs.js";
|
|
3
|
+
import { type StudyRoute } from "./study/plan.js";
|
|
4
|
+
import type { StudyDeps } from "./study/study-deps.js";
|
|
5
|
+
import type { RunStudyDriving, RunStudyHomes } from "./study/run-study-homes.js";
|
|
6
|
+
import { type StudyConfig } from "./study/types.js";
|
|
7
|
+
import type { ObserverResult } from "./observer/render.js";
|
|
8
|
+
import { type CuaActorStudyResult } from "./routes/computer-use/types.js";
|
|
9
|
+
import { type PreviewStudyResult } from "./routes/preview.js";
|
|
10
|
+
import { type ScriptedBrowserStudyResult } from "./routes/scripted/types.js";
|
|
11
|
+
import { type ConcurrentSharedWorldStudyResult } from "./routes/shared-world/types.js";
|
|
12
|
+
import { type TerminalProductStudyResult } from "./routes/terminal/types.js";
|
|
13
|
+
import { type RunScorerProvenance } from "./run/bundle.js";
|
|
14
|
+
import type { RunStudyProvenance } from "./run/study-provenance.js";
|
|
15
|
+
/**
|
|
16
|
+
* Runs a study on its route. The options are checked against the route and mapped into the route's
|
|
17
|
+
* hook bags before anything runs. Each route closes the run it started on every exit through its
|
|
18
|
+
* own run scope (`src/run/run.ts`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function runStudyWith(config: StudyConfig, options: InternalRunStudyOptions, deps?: StudyDeps): Promise<StudyOutcome>;
|
|
21
|
+
/**
|
|
22
|
+
* The package's study runner (`src/index.ts`): runStudyWith with the public options only. A
|
|
23
|
+
* JavaScript caller that passes a field RunStudyOptions no longer has, or a humanish.lab.v2 config,
|
|
24
|
+
* is refused in the route's own result envelope before anything runs.
|
|
25
|
+
*/
|
|
26
|
+
export declare function runStudy(config: StudyConfig, options: RunStudyOptions): Promise<StudyOutcome>;
|
|
27
|
+
/** A study planned once: the route's refusal, or the run of its plan. */
|
|
28
|
+
export type PreparedStudy = {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly outcome: StudyOutcome;
|
|
31
|
+
} | {
|
|
32
|
+
readonly ok: true;
|
|
33
|
+
/** Runs the plan. A scorer loaded after planning joins the run's hooks; it changes no plan. */
|
|
34
|
+
run(scorer?: LateScorer): Promise<StudyOutcome>;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Normalizes the options and plans the study once, so a caller can present a refusal before it loads
|
|
38
|
+
* anything the run needs. A local browser study's provider is bound first, so the plan is made with
|
|
39
|
+
* it, and its desktop goes to the computer-use run as `localVm`; with inProcess the caller drives
|
|
40
|
+
* the app in process and needs no desktop.
|
|
41
|
+
*/
|
|
42
|
+
export declare function prepareStudy(config: StudyConfig, options: InternalRunStudyOptions, deps?: StudyDeps): Promise<PreparedStudy>;
|
|
43
|
+
/**
|
|
44
|
+
* What a package caller passes to runStudy: the run's settings and the typed homes (`RunStudyHomes`,
|
|
45
|
+
* `RunStudyDriving`). Each wins over the config when provided.
|
|
46
|
+
*/
|
|
47
|
+
export type RunStudyOptions = RunStudyBase & RunStudyHomes & RunStudyDriving;
|
|
48
|
+
interface RunStudyBase {
|
|
49
|
+
cwd: string;
|
|
50
|
+
runId?: string;
|
|
51
|
+
dryRun?: boolean;
|
|
52
|
+
open?: boolean;
|
|
53
|
+
/** Participant count override: preview participants or computer-use desktops. */
|
|
54
|
+
count?: number;
|
|
55
|
+
/** CUA fan-out only: create a new run for failed/selected participants from a prior run. */
|
|
56
|
+
rerun?: {
|
|
57
|
+
sourceRunId: string;
|
|
58
|
+
participantIds?: string[];
|
|
59
|
+
};
|
|
60
|
+
onObserverReady?: (observer: ObserverResult & {
|
|
61
|
+
ok: true;
|
|
62
|
+
}) => Promise<void> | void;
|
|
63
|
+
}
|
|
64
|
+
/** runStudyWith's options inside the package: the public ones plus what only the CLI and tests set. */
|
|
65
|
+
export type InternalRunStudyOptions = RunStudyOptions & RunStudyInternals;
|
|
66
|
+
interface RunStudyInternals {
|
|
67
|
+
/**
|
|
68
|
+
* Which manifest this run came from. planStudy puts it on the plan, and the route reads
|
|
69
|
+
* plan.study for the run's status record and bundle. Absent for a library caller that passes a
|
|
70
|
+
* StudyConfig directly; that run records no study.
|
|
71
|
+
*/
|
|
72
|
+
study?: RunStudyProvenance;
|
|
73
|
+
/**
|
|
74
|
+
* Config-declared scorer provenance, forwarded alongside the
|
|
75
|
+
* loaded scorer. Its presence is the "declared" marker the terminal route reads to flip a
|
|
76
|
+
* status:"fail" verdict; the browser routes stamp it as evidence (they already flip). Core-computed
|
|
77
|
+
* (path + digest), never adopter-supplied; absent for library callers.
|
|
78
|
+
*/
|
|
79
|
+
scorerProvenance?: RunScorerProvenance;
|
|
80
|
+
/** The local VM study's desktop, analysis gate and signal, for a local browser study. */
|
|
81
|
+
localVm?: LocalVmInput;
|
|
82
|
+
}
|
|
83
|
+
/** A run's result and the route it ran on. */
|
|
84
|
+
interface RouteOutcome<R extends StudyRoute, T> {
|
|
85
|
+
route: R;
|
|
86
|
+
result: T;
|
|
87
|
+
}
|
|
88
|
+
export type StudyOutcome = RouteOutcome<"preview", PreviewStudyResult> | RouteOutcome<"computer-use", CuaActorStudyResult> | RouteOutcome<"scripted", ScriptedBrowserStudyResult> | RouteOutcome<"terminal", TerminalProductStudyResult> | RouteOutcome<"shared-world", ConcurrentSharedWorldStudyResult>;
|
|
89
|
+
/**
|
|
90
|
+
* A plan past its route's local checks that need no scorer: the refusal they returned, or the
|
|
91
|
+
* route's run, which takes a scorer loaded after them.
|
|
92
|
+
*/
|
|
93
|
+
export type AdmittedPlan<R extends StudyRoute = StudyRoute> = {
|
|
94
|
+
readonly ok: false;
|
|
95
|
+
readonly outcome: Extract<StudyOutcome, {
|
|
96
|
+
route: R;
|
|
97
|
+
}>;
|
|
98
|
+
} | {
|
|
99
|
+
readonly ok: true;
|
|
100
|
+
run(scorer?: LateScorer): Promise<Extract<StudyOutcome, {
|
|
101
|
+
route: R;
|
|
102
|
+
}>>;
|
|
103
|
+
};
|
|
104
|
+
/** The result of a run on route `R`, the `result` of that route's `StudyOutcome`. */
|
|
105
|
+
export type StudyResult<R extends StudyRoute = StudyRoute> = {
|
|
106
|
+
preview: PreviewStudyResult;
|
|
107
|
+
"computer-use": CuaActorStudyResult;
|
|
108
|
+
scripted: ScriptedBrowserStudyResult;
|
|
109
|
+
terminal: TerminalProductStudyResult;
|
|
110
|
+
"shared-world": ConcurrentSharedWorldStudyResult;
|
|
111
|
+
}[R];
|
|
112
|
+
export {};
|
|
@@ -1,72 +1,79 @@
|
|
|
1
|
-
//
|
|
2
|
-
// and provider, and plans the
|
|
1
|
+
// runStudyWith runs one study. It normalizes the caller's options, binds a local browser study's desktop
|
|
2
|
+
// and provider, and plans the study once with planStudy. A refused plan returns the route's own result
|
|
3
3
|
// envelope before anything starts. One switch on plan.route then calls the route's admit function,
|
|
4
4
|
// which runs the route's local checks that need no scorer (keys, subject env, the local agent) and
|
|
5
|
-
// returns the route's run.
|
|
5
|
+
// returns the route's run. prepareStudy is the same path in two steps, so the CLI can present either
|
|
6
6
|
// refusal before it loads a declared review scorer.
|
|
7
|
-
import { computerUseInput, scriptedInput, sharedWorldInput, terminalInput, } from "./
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {} from "./
|
|
11
|
-
import {
|
|
7
|
+
import { computerUseInput, scriptedInput, sharedWorldInput, terminalInput, } from "./study/route-inputs.js";
|
|
8
|
+
import { planStudy, resolveStudyDryRun, routeOf } from "./study/plan.js";
|
|
9
|
+
import { normalizeRunStudyOptions, optionRefusalOutcome, removedOptionRefusal, } from "./study/run-study-options.js";
|
|
10
|
+
import { V2_SCHEMA } from "./study/types.js";
|
|
11
|
+
import { V2_UNSUPPORTED_MESSAGE } from "./study/config.js";
|
|
12
|
+
import { admitComputerUsePlan, computerUseStudyRefusal } from "./routes/computer-use/route.js";
|
|
12
13
|
import {} from "./routes/computer-use/types.js";
|
|
13
|
-
import { admitPreviewPlan,
|
|
14
|
-
import { admitScriptedPlan,
|
|
14
|
+
import { admitPreviewPlan, previewStudyRefusal, } from "./routes/preview.js";
|
|
15
|
+
import { admitScriptedPlan, scriptedStudyRefusal } from "./routes/scripted/route.js";
|
|
15
16
|
import {} from "./routes/scripted/types.js";
|
|
16
|
-
import { admitSharedWorldPlan,
|
|
17
|
+
import { admitSharedWorldPlan, sharedWorldStudyRefusal } from "./routes/shared-world/route.js";
|
|
17
18
|
import {} from "./routes/shared-world/types.js";
|
|
18
|
-
import { admitTerminalPlan,
|
|
19
|
+
import { admitTerminalPlan, terminalStudyRefusal } from "./routes/terminal/route.js";
|
|
19
20
|
import {} from "./routes/terminal/types.js";
|
|
20
21
|
import {} from "./run/bundle.js";
|
|
21
|
-
import {
|
|
22
|
+
import { isLocalBrowserStudy, localBrowserDefaults } from "./substrates/local/runtime-config.js";
|
|
22
23
|
/**
|
|
23
|
-
* Runs a
|
|
24
|
+
* Runs a study on its route. The options are checked against the route and mapped into the route's
|
|
24
25
|
* hook bags before anything runs. Each route closes the run it started on every exit through its
|
|
25
26
|
* own run scope (`src/run/run.ts`).
|
|
26
27
|
*/
|
|
27
|
-
export async function
|
|
28
|
-
const prepared = await
|
|
28
|
+
export async function runStudyWith(config, options, deps = {}) {
|
|
29
|
+
const prepared = await prepareStudy(config, options, deps);
|
|
29
30
|
return prepared.ok ? prepared.run() : prepared.outcome;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
|
-
*
|
|
33
|
-
* that passes a field
|
|
34
|
-
* before anything runs.
|
|
33
|
+
* The package's study runner (`src/index.ts`): runStudyWith with the public options only. A
|
|
34
|
+
* JavaScript caller that passes a field RunStudyOptions no longer has, or a humanish.lab.v2 config,
|
|
35
|
+
* is refused in the route's own result envelope before anything runs.
|
|
35
36
|
*/
|
|
36
|
-
export async function
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
export async function runStudy(config, options) {
|
|
38
|
+
const refusal = config.schema === V2_SCHEMA
|
|
39
|
+
? {
|
|
40
|
+
ok: false,
|
|
41
|
+
code: "HUMANISH_STUDY_V2_UNSUPPORTED",
|
|
42
|
+
message: V2_UNSUPPORTED_MESSAGE,
|
|
43
|
+
}
|
|
44
|
+
: removedOptionRefusal(options);
|
|
45
|
+
if (refusal === undefined)
|
|
46
|
+
return runStudyWith(config, options);
|
|
47
|
+
const study = localBrowserDefaults(config);
|
|
48
|
+
return optionRefusalOutcome(study, routeOf(study), options, refusal);
|
|
42
49
|
}
|
|
43
50
|
/**
|
|
44
|
-
* Normalizes the options and plans the
|
|
51
|
+
* Normalizes the options and plans the study once, so a caller can present a refusal before it loads
|
|
45
52
|
* anything the run needs. A local browser study's provider is bound first, so the plan is made with
|
|
46
53
|
* it, and its desktop goes to the computer-use run as `localVm`; with inProcess the caller drives
|
|
47
54
|
* the app in process and needs no desktop.
|
|
48
55
|
*/
|
|
49
|
-
export async function
|
|
50
|
-
const
|
|
51
|
-
const route = routeOf(
|
|
52
|
-
const normalized =
|
|
56
|
+
export async function prepareStudy(config, options, deps = {}) {
|
|
57
|
+
const study = localBrowserDefaults(config);
|
|
58
|
+
const route = routeOf(study);
|
|
59
|
+
const normalized = normalizeRunStudyOptions(study, route, options);
|
|
53
60
|
if (!normalized.ok)
|
|
54
|
-
return { ok: false, outcome: optionRefusalOutcome(
|
|
61
|
+
return { ok: false, outcome: optionRefusalOutcome(study, route, options, normalized) };
|
|
55
62
|
// An in-process executor needs no desktop, and a caller that already prepared the study passes
|
|
56
63
|
// its localVm, which a second study would replace.
|
|
57
|
-
const prepareLocalVm =
|
|
64
|
+
const prepareLocalVm = isLocalBrowserStudy(study) && options.inProcess === undefined && options.localVm === undefined
|
|
58
65
|
? (await import("./routes/computer-use/local-vm.js")).prepareLocalVmRun
|
|
59
66
|
: undefined;
|
|
60
|
-
const vm = prepareLocalVm?.({ ...normalized.options, config:
|
|
67
|
+
const vm = prepareLocalVm?.({ ...normalized.options, config: study });
|
|
61
68
|
const planning = vm === undefined ? normalized.options : { ...vm.options, localVm: vm.localVm };
|
|
62
|
-
const planned =
|
|
69
|
+
const planned = planStudy(study, planning, deps);
|
|
63
70
|
if (!planned.ok) {
|
|
64
71
|
await vm?.close();
|
|
65
|
-
const outcome = await refusalOutcome(
|
|
72
|
+
const outcome = await refusalOutcome(study, planning, planned.refusal, deps, normalized.emit);
|
|
66
73
|
outcome.result.warnings.push(...normalized.warnings);
|
|
67
74
|
return { ok: false, outcome };
|
|
68
75
|
}
|
|
69
|
-
const admitted = await admitPlan(
|
|
76
|
+
const admitted = await admitPlan(study, planning, planned.planned.plan, deps, normalized.emit);
|
|
70
77
|
if (!admitted.ok) {
|
|
71
78
|
await vm?.close();
|
|
72
79
|
admitted.outcome.result.warnings.push(...normalized.warnings);
|
|
@@ -81,9 +88,9 @@ export async function prepareLab(config, options, deps = {}) {
|
|
|
81
88
|
if (scorer !== undefined) {
|
|
82
89
|
// Checks the scorer against the route and the caller's options, as if passed up front.
|
|
83
90
|
// Only its refusal is used; its options and warnings array are not.
|
|
84
|
-
const withScorer =
|
|
91
|
+
const withScorer = normalizeRunStudyOptions(study, route, { ...options, ...scorer });
|
|
85
92
|
if (!withScorer.ok) {
|
|
86
|
-
const outcome = optionRefusalOutcome(
|
|
93
|
+
const outcome = optionRefusalOutcome(study, route, options, withScorer);
|
|
87
94
|
outcome.result.warnings.push(...normalized.warnings);
|
|
88
95
|
return outcome;
|
|
89
96
|
}
|
|
@@ -118,33 +125,33 @@ async function admitPlan(config, options, plan, deps, emit) {
|
|
|
118
125
|
}
|
|
119
126
|
/** The refused route's own result, with the envelope and analysis record its runner returns. */
|
|
120
127
|
async function refusalOutcome(config, options, refusal, deps, emit) {
|
|
121
|
-
// Spend-safe default: a
|
|
122
|
-
const dryRun =
|
|
128
|
+
// Spend-safe default: a study goes live only when the config (or CLI) says so.
|
|
129
|
+
const dryRun = resolveStudyDryRun(config, options.dryRun, true) ?? true;
|
|
123
130
|
switch (refusal.route) {
|
|
124
131
|
case "preview":
|
|
125
132
|
return {
|
|
126
133
|
route: "preview",
|
|
127
|
-
result:
|
|
134
|
+
result: previewStudyRefusal(options.cwd, config.id, refusal),
|
|
128
135
|
};
|
|
129
136
|
case "computer-use":
|
|
130
137
|
return {
|
|
131
138
|
route: "computer-use",
|
|
132
|
-
result: await
|
|
139
|
+
result: await computerUseStudyRefusal({ ...computerUseInput(options, deps, emit), config, dryRun }, refusal),
|
|
133
140
|
};
|
|
134
141
|
case "scripted":
|
|
135
142
|
return {
|
|
136
143
|
route: "scripted",
|
|
137
|
-
result: await
|
|
144
|
+
result: await scriptedStudyRefusal({ ...scriptedInput(options, deps, emit), config, dryRun }, refusal),
|
|
138
145
|
};
|
|
139
146
|
case "terminal":
|
|
140
147
|
return {
|
|
141
148
|
route: "terminal",
|
|
142
|
-
result: await
|
|
149
|
+
result: await terminalStudyRefusal({ ...terminalInput(options, deps, emit), config, dryRun }, refusal),
|
|
143
150
|
};
|
|
144
151
|
case "shared-world":
|
|
145
152
|
return {
|
|
146
153
|
route: "shared-world",
|
|
147
|
-
result: await
|
|
154
|
+
result: await sharedWorldStudyRefusal({ ...sharedWorldInput(options, deps, emit), config, dryRun }, refusal),
|
|
148
155
|
};
|
|
149
156
|
}
|
|
150
157
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { RunAdapterArtifact, RunAdapterScore, RunBundle, RunFeedbackCandidate, RunScorerProvenance } from "../run/bundle.js";
|
|
2
|
-
type BrowserAdapterBackend = "cua" | "shared-world" | "concurrent-shared-world";
|
|
3
2
|
/** The routes that call a browser scorer. */
|
|
4
3
|
type BrowserScorerRoute = "computer-use" | "shared-world";
|
|
5
4
|
/**
|
|
@@ -7,7 +6,7 @@ type BrowserScorerRoute = "computer-use" | "shared-world";
|
|
|
7
6
|
* evidence/rubrics stay in the adopter's repo; core provides the assembled bundle
|
|
8
7
|
* plus stable run identifiers and never learns product nouns.
|
|
9
8
|
*/
|
|
10
|
-
export interface
|
|
9
|
+
export interface BrowserScoringContext {
|
|
11
10
|
bundle: RunBundle;
|
|
12
11
|
/**
|
|
13
12
|
* Absolute path to the ignored run directory. Adapter hooks may write their
|
|
@@ -15,28 +14,17 @@ export interface BrowserLabScoringContext {
|
|
|
15
14
|
* `deriveArtifacts`. This path is runtime-only and must never be persisted.
|
|
16
15
|
*/
|
|
17
16
|
runDir: string;
|
|
18
|
-
|
|
17
|
+
/** The study id. */
|
|
18
|
+
studyId: string;
|
|
19
19
|
runId: string;
|
|
20
20
|
actor: string;
|
|
21
21
|
/** The route that ran the participants. */
|
|
22
22
|
route: BrowserScorerRoute;
|
|
23
|
-
/**
|
|
24
|
-
* @deprecated Use `route`. `cua` is `computer-use` and `concurrent-shared-world` is
|
|
25
|
-
* `shared-world`. Reading it warns once per process; the next minor removes it.
|
|
26
|
-
*/
|
|
27
|
-
backend: BrowserAdapterBackend;
|
|
28
23
|
dryRun: boolean;
|
|
29
24
|
/** How many participants the run had. */
|
|
30
25
|
participantCount: number;
|
|
31
|
-
/**
|
|
32
|
-
* @deprecated Use `participantCount`, which has the same value. Reading it warns once per
|
|
33
|
-
* process; the next minor removes it.
|
|
34
|
-
*/
|
|
35
|
-
laneCount: number;
|
|
36
26
|
}
|
|
37
|
-
/** The
|
|
38
|
-
type BrowserScoringFacts = Omit<BrowserLabScoringContext, "backend" | "laneCount">;
|
|
39
|
-
/** The scorer functions a computer-use or shared-world run calls: `RunLabOptions.scorer`. */
|
|
27
|
+
/** The scorer functions a computer-use or shared-world run calls: `RunStudyOptions.scorer`. */
|
|
40
28
|
export interface BrowserScorer {
|
|
41
29
|
/**
|
|
42
30
|
* Browser-route extension seam: a thin adapter may score the assembled
|
|
@@ -44,20 +32,20 @@ export interface BrowserScorer {
|
|
|
44
32
|
* namespaced `bundle.adapterScore`; product-specific component detail belongs
|
|
45
33
|
* in `data`, not in core enums or review text.
|
|
46
34
|
*/
|
|
47
|
-
score?: (ctx:
|
|
35
|
+
score?: (ctx: BrowserScoringContext) => RunAdapterScore | Promise<RunAdapterScore>;
|
|
48
36
|
/**
|
|
49
37
|
* Companion seam for public-safe, adapter-namespaced feedback candidates.
|
|
50
38
|
* Malformed candidates are dropped before bundle persistence so core remains
|
|
51
39
|
* verifiable even when an adapter misbehaves.
|
|
52
40
|
*/
|
|
53
|
-
deriveFeedback?: (ctx:
|
|
41
|
+
deriveFeedback?: (ctx: BrowserScoringContext) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
|
|
54
42
|
/**
|
|
55
43
|
* Optional product/state proof artifact references. The adapter writes files
|
|
56
44
|
* under `ctx.runDir` and returns local relative paths. Core stores only the
|
|
57
45
|
* namespaced references and `verify` fails closed if referenced files are
|
|
58
46
|
* missing or nonlocal.
|
|
59
47
|
*/
|
|
60
|
-
deriveArtifacts?: (ctx:
|
|
48
|
+
deriveArtifacts?: (ctx: BrowserScoringContext) => RunAdapterArtifact[] | Promise<RunAdapterArtifact[]>;
|
|
61
49
|
}
|
|
62
50
|
/** What a scorer found against the run, for the route's final review fold (foldScorerFailures). */
|
|
63
51
|
export interface ScorerOutcome {
|
|
@@ -70,7 +58,7 @@ export declare const DECLARED_SCORER_MALFORMED = "Declared product scorer return
|
|
|
70
58
|
export declare function declaredScorerThrew(detail: string): string;
|
|
71
59
|
export declare function applyBrowserScorer(args: {
|
|
72
60
|
scorer: BrowserScorer | undefined;
|
|
73
|
-
context:
|
|
61
|
+
context: BrowserScoringContext;
|
|
74
62
|
bundle: RunBundle;
|
|
75
63
|
sanitize: (text: string) => string;
|
|
76
64
|
warnings: string[];
|
|
@@ -1,19 +1,7 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { isRunAdapterScore } from "../run/bundle-shape.js";
|
|
3
|
-
import { withDeprecatedFields } from "./deprecated-fields.js";
|
|
4
3
|
import { isRunFeedbackCandidate } from "../run/feedback-shape.js";
|
|
5
4
|
import { isRecord } from "../run/type-guards.js";
|
|
6
|
-
const OLDER_BACKEND = {
|
|
7
|
-
"computer-use": "cua",
|
|
8
|
-
"shared-world": "concurrent-shared-world",
|
|
9
|
-
};
|
|
10
|
-
/** The scorer's context: the facts, plus the older `backend` and `laneCount` (deprecated-fields.ts). */
|
|
11
|
-
function scorerContext(facts) {
|
|
12
|
-
return withDeprecatedFields({ ...facts }, { name: "BrowserLabScoringContext", code: "HUMANISH_SCORING_CONTEXT_FIELD_DEPRECATED" }, {
|
|
13
|
-
backend: { replacement: "route", read: () => OLDER_BACKEND[facts.route] },
|
|
14
|
-
laneCount: { replacement: "participantCount", read: () => facts.participantCount },
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
5
|
/** A declared scorer that returned a malformed value never rendered a verdict. */
|
|
18
6
|
export const DECLARED_SCORER_MALFORMED = "Declared product scorer returned a malformed value instead of a verdict; a declared gate that cannot render a pass is recorded as a fail, never a silent pass.";
|
|
19
7
|
/** A declared scorer that threw never rendered a verdict. `detail` is already sanitized. */
|
|
@@ -33,10 +21,10 @@ export async function applyBrowserScorer(args) {
|
|
|
33
21
|
// The scorer sees a read-only view of the bundle: it cannot mutate noSpend/cost/review in place to
|
|
34
22
|
// launder a verdict (a tamper attempt throws in the scorer's strict-mode ESM and is caught below as
|
|
35
23
|
// a hook failure). The seam still stamps the real bundle.
|
|
36
|
-
const scoringContext =
|
|
24
|
+
const scoringContext = {
|
|
37
25
|
...context,
|
|
38
26
|
bundle: frozenBundleView(context.bundle),
|
|
39
|
-
}
|
|
27
|
+
};
|
|
40
28
|
const scrubValue = (value) => {
|
|
41
29
|
const encoded = JSON.stringify(value);
|
|
42
30
|
return encoded === undefined ? value : JSON.parse(sanitize(encoded));
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BrowserScoringContext } from "./adapter-extension.js";
|
|
2
2
|
import type { TerminalProductScoringContext } from "../routes/terminal/types.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { StudyRoute } from "./plan.js";
|
|
4
4
|
import type { RunAdapterArtifact, RunAdapterScore, RunFeedbackCandidate, RunScorerProvenance } from "../run/bundle.js";
|
|
5
5
|
/** The read-model context a loaded scorer sees: the terminal or browser scoring context. The module
|
|
6
6
|
* narrows it at runtime (`"product" in ctx` ⇒ terminal; `"route" in ctx` ⇒ browser). */
|
|
7
|
-
export type AdapterScoringContext = TerminalProductScoringContext |
|
|
7
|
+
export type AdapterScoringContext = TerminalProductScoringContext | BrowserScoringContext;
|
|
8
8
|
/**
|
|
9
9
|
* The adopter-facing scorer module contract. Export any subset of these from a `.mjs` (or a
|
|
10
10
|
* `.js`/`.cjs` whose package.json type matches): named exports or a single default object. The
|
|
11
11
|
* loader wires only these three; an exported `executor`/`env`/`provisionSubject`/`costProbe` is never
|
|
12
12
|
* picked up (the whitelist is the scope guard). A module exporting none of them is a hard load error.
|
|
13
13
|
*
|
|
14
|
-
* `C` is the context `score` and `deriveFeedback` read: `
|
|
14
|
+
* `C` is the context `score` and `deriveFeedback` read: `BrowserScoringContext` for a scorer
|
|
15
15
|
* written for computer use and shared world, `TerminalProductScoringContext` for one written for
|
|
16
16
|
* terminal runs, or the default union for one that narrows at runtime.
|
|
17
17
|
*/
|
|
@@ -19,22 +19,22 @@ export interface AdapterScorerModule<C extends AdapterScoringContext = AdapterSc
|
|
|
19
19
|
score?: (ctx: C) => RunAdapterScore | Promise<RunAdapterScore>;
|
|
20
20
|
deriveFeedback?: (ctx: C) => RunFeedbackCandidate[] | Promise<RunFeedbackCandidate[]>;
|
|
21
21
|
/** Browser-route only; inert on the terminal route, whose TerminalScorer has no artifacts seam. */
|
|
22
|
-
deriveArtifacts?: (ctx:
|
|
22
|
+
deriveArtifacts?: (ctx: BrowserScoringContext) => RunAdapterArtifact[] | Promise<RunAdapterArtifact[]>;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* A scorer written for computer use and shared world, as `
|
|
25
|
+
* A scorer written for computer use and shared world, as `RunStudyOptions.scorer` takes it. Those
|
|
26
26
|
* routes pass the browser context; another route that calls it passes a context it was not written
|
|
27
27
|
* for. The call states the kind, so the module itself needs no cast.
|
|
28
28
|
*/
|
|
29
|
-
export declare function browserScorer(scorer: AdapterScorerModule<
|
|
30
|
-
/** A scorer written for terminal runs, as `
|
|
29
|
+
export declare function browserScorer(scorer: AdapterScorerModule<BrowserScoringContext>): AdapterScorerModule;
|
|
30
|
+
/** A scorer written for terminal runs, as `RunStudyOptions.scorer` takes it (see browserScorer). */
|
|
31
31
|
export declare function terminalScorer(scorer: AdapterScorerModule<TerminalProductScoringContext>): AdapterScorerModule;
|
|
32
32
|
/**
|
|
33
33
|
* The scorer as a computer-use or shared-world run calls it, with the browser context. The caller
|
|
34
34
|
* chose the context it wrote the scorer for; only the route knows which context it passes, so the
|
|
35
35
|
* narrowing is here. A terminal-typed scorer on a browser route reads fields the context lacks.
|
|
36
36
|
*/
|
|
37
|
-
export declare function browserRouteScorer(scorer: AdapterScorerModule): AdapterScorerModule<
|
|
37
|
+
export declare function browserRouteScorer(scorer: AdapterScorerModule): AdapterScorerModule<BrowserScoringContext>;
|
|
38
38
|
/** The scorer as a terminal run calls it, with the terminal context (see browserRouteScorer). */
|
|
39
39
|
export declare function terminalRouteScorer(scorer: AdapterScorerModule): AdapterScorerModule<TerminalProductScoringContext>;
|
|
40
40
|
type AdapterScorerLoadErrorCode = "HUMANISH_STUDY_SCORER_BAD_REF" | "HUMANISH_STUDY_SCORER_NOT_FOUND" | "HUMANISH_STUDY_SCORER_LOAD_FAILED" | "HUMANISH_STUDY_SCORER_NO_HOOKS" | "HUMANISH_STUDY_SCORER_UNSUPPORTED_BACKEND";
|
|
@@ -57,7 +57,7 @@ export type AdapterScorerLoadResult = {
|
|
|
57
57
|
export declare function loadAdapterScorer(args: {
|
|
58
58
|
cwd: string;
|
|
59
59
|
ref: string;
|
|
60
|
-
route:
|
|
60
|
+
route: StudyRoute;
|
|
61
61
|
source: "manifest" | "cli-flag";
|
|
62
62
|
}): Promise<AdapterScorerLoadResult>;
|
|
63
63
|
export {};
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// satisfied no-spend proof, so it stays library-only.
|
|
6
6
|
//
|
|
7
7
|
// Trust model: the party who writes `review.scorer.ref` is the party
|
|
8
|
-
// who runs `humanish
|
|
8
|
+
// who runs `humanish run` in their own checkout: identical trust to humanish.lab.yml or a
|
|
9
9
|
// package.json script. The loader adds no new execution capability; it relocates where the reference is
|
|
10
10
|
// declared. Containment is entry-file-only: `readContainedRegularFile` blocks abs/`..`/symlink/
|
|
11
11
|
// hardlink/realpath-escape/TOCTOU on the entry module, but `import()` then executes the transitive
|
|
@@ -20,14 +20,14 @@ import { pathToFileURL } from "node:url";
|
|
|
20
20
|
import { digestText, redactText } from "../evidence/redaction.js";
|
|
21
21
|
import { prepareSelectedOutputDirectory, readContainedRegularFile, } from "../run/contained-output.js";
|
|
22
22
|
/**
|
|
23
|
-
* A scorer written for computer use and shared world, as `
|
|
23
|
+
* A scorer written for computer use and shared world, as `RunStudyOptions.scorer` takes it. Those
|
|
24
24
|
* routes pass the browser context; another route that calls it passes a context it was not written
|
|
25
25
|
* for. The call states the kind, so the module itself needs no cast.
|
|
26
26
|
*/
|
|
27
27
|
export function browserScorer(scorer) {
|
|
28
28
|
return scorer;
|
|
29
29
|
}
|
|
30
|
-
/** A scorer written for terminal runs, as `
|
|
30
|
+
/** A scorer written for terminal runs, as `RunStudyOptions.scorer` takes it (see browserScorer). */
|
|
31
31
|
export function terminalScorer(scorer) {
|
|
32
32
|
return scorer;
|
|
33
33
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StudyConfig } from "./types.js";
|
|
2
|
+
/** The first composition rule a config breaks, in the parser's order, or null. */
|
|
3
|
+
export declare function compositionReason(config: StudyConfig): string | null;
|
|
4
|
+
/** Why a this-repo study cannot run live. The parser and the preview planner both refuse with it. */
|
|
5
|
+
export declare const THIS_REPO_DRY_RUN_ONLY = "this-repo studies are dry-run only; use a clone or app-url subject for a live run.";
|
|
6
|
+
/** A desktop-cli subject with no product to study. The computer-use planner checks this too. */
|
|
7
|
+
export declare function desktopCliProductReason(config: StudyConfig): string | null;
|