humanish 0.107.0 → 0.108.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +22 -17
- package/CHANGELOG.md +14 -0
- package/CONTEXT.md +51 -44
- package/README.md +145 -172
- package/SECURITY.md +16 -26
- package/TELEMETRY.md +8 -6
- package/dist/actors/affordance.d.ts +4 -4
- package/dist/actors/affordance.js +12 -12
- package/dist/actors/agent-session.d.ts +2 -2
- package/dist/actors/agent-session.js +7 -7
- package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
- package/dist/actors/codex/app-server-actor-trace.js +1 -1
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/restricted-executable.d.ts +4 -4
- package/dist/actors/codex/restricted-executable.js +8 -8
- package/dist/actors/codex/restricted-launch.d.ts +2 -1
- package/dist/actors/codex/restricted-launch.js +1 -1
- package/dist/actors/codex/restricted-participant.js +8 -6
- package/dist/actors/codex/restricted-policy.d.ts +2 -2
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +2 -2
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +16 -16
- package/dist/actors/computer-use/actor.js +2 -2
- package/dist/actors/computer-use/admission-limit.d.ts +1 -1
- package/dist/actors/computer-use/admission-limit.js +1 -1
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +10 -10
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +14 -12
- package/dist/actors/computer-use/loop/ending.d.ts +5 -5
- package/dist/actors/computer-use/loop/ending.js +7 -7
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +9 -9
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +1 -1
- package/dist/actors/computer-use/loop/session.js +3 -3
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +1 -1
- package/dist/actors/computer-use/loop/trace.js +9 -8
- package/dist/actors/computer-use/loop/types.d.ts +25 -23
- package/dist/actors/computer-use/loop/usage.js +2 -2
- package/dist/actors/computer-use/openai-context.d.ts +37 -0
- package/dist/actors/computer-use/openai-context.js +214 -0
- package/dist/actors/computer-use/openai-provider.d.ts +11 -8
- package/dist/actors/computer-use/openai-provider.js +45 -34
- package/dist/actors/computer-use/openai-requests.d.ts +36 -10
- package/dist/actors/computer-use/openai-requests.js +82 -15
- package/dist/actors/computer-use/openai-wire.d.ts +19 -7
- package/dist/actors/computer-use/openai-wire.js +36 -34
- package/dist/actors/contract.d.ts +78 -43
- package/dist/actors/contract.js +29 -23
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +10 -9
- package/dist/actors/local-agent/cli.d.ts +8 -6
- package/dist/actors/local-agent/cli.js +24 -28
- package/dist/actors/local-agent/readiness.d.ts +2 -2
- package/dist/actors/local-agent/readiness.js +4 -4
- package/dist/actors/reasoning-effort.js +6 -6
- package/dist/actors/registry.d.ts +10 -10
- package/dist/actors/registry.js +18 -17
- package/dist/actors/scripted-browser/actor.d.ts +8 -8
- package/dist/actors/scripted-browser/actor.js +16 -16
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/steps.js +1 -1
- package/dist/actors/scripted-browser/types.d.ts +1 -1
- package/dist/actors/stop-conditions.d.ts +1 -1
- package/dist/analysis/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/service.js +5 -5
- package/dist/cli/commands/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +54 -33
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/lab-format.d.ts +5 -4
- package/dist/cli/commands/lab-format.js +35 -23
- package/dist/cli/commands/lab-route-computer-use.js +6 -7
- package/dist/cli/commands/lab-route-preview.js +4 -3
- package/dist/cli/commands/lab-route-shared-world.js +3 -3
- package/dist/cli/commands/lab-run.js +10 -11
- package/dist/cli/commands/lab-scorer.d.ts +2 -2
- package/dist/cli/commands/lab-scorer.js +1 -1
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.js +147 -108
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/runs.js +137 -138
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +26 -21
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +182 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +21 -21
- package/dist/cli/commands/watch.js +60 -75
- package/dist/cli/deprecations.d.ts +18 -0
- package/dist/cli/deprecations.js +48 -0
- package/dist/cli/doctor.d.ts +15 -5
- package/dist/cli/doctor.js +103 -48
- package/dist/cli/first-run-path.d.ts +12 -10
- package/dist/cli/first-run-path.js +30 -28
- package/dist/cli/io.d.ts +41 -6
- package/dist/cli/io.js +97 -22
- package/dist/cli/observer-follow.d.ts +2 -2
- package/dist/cli/observer-follow.js +5 -6
- package/dist/cli/orientation.d.ts +6 -3
- package/dist/cli/orientation.js +43 -39
- package/dist/cli/product-sentence.d.ts +6 -0
- package/dist/cli/product-sentence.js +6 -0
- package/dist/cli/program.d.ts +6 -1
- package/dist/cli/program.js +109 -40
- package/dist/cli/telemetry.d.ts +15 -15
- package/dist/cli/telemetry.js +48 -40
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +13 -12
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +7 -7
- package/dist/comms/catch-host.js +14 -14
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.js +2 -2
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +2 -2
- package/dist/comms/fake-inbox.js +2 -2
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- package/dist/comms/sandbox-catch-script.d.ts +6 -6
- package/dist/comms/sandbox-catch-script.js +6 -6
- package/dist/comms/sandbox-catch.d.ts +36 -37
- package/dist/comms/sandbox-catch.js +34 -35
- package/dist/comms/setup.js +42 -8
- package/dist/comms/thread-evidence.d.ts +1 -1
- package/dist/comms/thread-evidence.js +6 -6
- package/dist/comms/types.d.ts +6 -6
- package/dist/comms/types.js +3 -3
- package/dist/evidence/frame-signature.d.ts +1 -1
- package/dist/evidence/frame-signature.js +4 -4
- package/dist/evidence/redaction.d.ts +3 -3
- package/dist/evidence/redaction.js +4 -4
- package/dist/feedback/draft.js +36 -78
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +7 -8
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- package/dist/guest/chromium-text.js +2 -2
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/runtime.js +1 -1
- package/dist/index.d.ts +12 -10
- package/dist/index.js +8 -6
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/lab/adapter-extension.d.ts +7 -7
- package/dist/lab/adapter-extension.js +13 -36
- package/dist/lab/adapter-scorer-loader.d.ts +7 -7
- package/dist/lab/adapter-scorer-loader.js +32 -32
- package/dist/lab/composition-rules.js +42 -42
- package/dist/lab/config.js +65 -25
- package/dist/lab/deprecated-fields.d.ts +10 -0
- package/dist/lab/deprecated-fields.js +24 -0
- package/dist/lab/device-presets.d.ts +8 -8
- package/dist/lab/device-presets.js +11 -11
- package/dist/lab/discover.d.ts +13 -9
- package/dist/lab/discover.js +117 -57
- package/dist/lab/doctor.d.ts +10 -3
- package/dist/lab/doctor.js +47 -9
- package/dist/lab/init-templates.js +147 -147
- package/dist/lab/init.d.ts +1 -1
- package/dist/lab/init.js +41 -9
- package/dist/lab/keys.d.ts +2 -0
- package/dist/lab/keys.js +42 -8
- package/dist/lab/lab-deps.d.ts +7 -12
- package/dist/lab/parse/actors.js +9 -9
- package/dist/lab/parse/comms.js +5 -5
- package/dist/lab/parse/execution.js +13 -13
- package/dist/lab/parse/study-v3.d.ts +23 -0
- package/dist/lab/parse/study-v3.js +259 -0
- package/dist/lab/parse/subject-state.d.ts +7 -7
- package/dist/lab/parse/subject-state.js +16 -16
- package/dist/lab/parse/subject.js +28 -28
- package/dist/lab/parse/values.d.ts +1 -1
- package/dist/lab/parse/values.js +3 -3
- package/dist/lab/persona-resolve.d.ts +4 -4
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/plan-participants.d.ts +2 -2
- package/dist/lab/plan-types.d.ts +4 -4
- package/dist/lab/plan.d.ts +1 -7
- package/dist/lab/plan.js +10 -41
- package/dist/lab/preflight-probes.js +11 -11
- package/dist/lab/preflight-result.d.ts +2 -1
- package/dist/lab/preflight-result.js +5 -4
- package/dist/lab/preflight.d.ts +7 -5
- package/dist/lab/preflight.js +5 -5
- package/dist/lab/routing.d.ts +31 -25
- package/dist/lab/routing.js +60 -29
- package/dist/lab/run-lab-events.d.ts +0 -3
- package/dist/lab/run-lab-events.js +0 -6
- package/dist/lab/run-lab-homes.d.ts +22 -10
- package/dist/lab/run-lab-homes.js +5 -1
- package/dist/lab/run-lab-options.d.ts +1 -1
- package/dist/lab/run-lab-options.js +16 -13
- package/dist/lab/summary.d.ts +7 -6
- package/dist/lab/summary.js +10 -10
- package/dist/lab/tasks.d.ts +15 -15
- package/dist/lab/tasks.js +14 -14
- package/dist/lab/types.d.ts +101 -95
- package/dist/lab/types.js +2 -0
- package/dist/lab/validation.d.ts +13 -13
- package/dist/lab/validation.js +44 -42
- package/dist/lab/warnings.d.ts +10 -0
- package/dist/lab/warnings.js +61 -33
- package/dist/library-aliases.d.ts +56 -0
- package/dist/library-aliases.js +22 -0
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +6 -6
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +5 -4
- package/dist/observer/exposure.d.ts +1 -1
- package/dist/observer/exposure.js +11 -11
- package/dist/observer/http.js +1 -1
- package/dist/observer/library.d.ts +1 -1
- package/dist/observer/library.js +4 -2
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +10 -5
- package/dist/observer/run-routes.d.ts +3 -3
- package/dist/observer/run-routes.js +1 -1
- package/dist/observer/serve.js +7 -3
- package/dist/observer/tunnel.js +1 -1
- package/dist/observer-app.html +4 -4
- package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
- package/dist/routes/computer-use/bundle-parts.js +15 -15
- package/dist/routes/computer-use/bundle.js +3 -3
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.js +14 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +4 -3
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/start.js +9 -8
- package/dist/routes/computer-use/e2b-desktop/teardown.js +5 -4
- package/dist/routes/computer-use/external-comms.d.ts +1 -1
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +18 -18
- package/dist/routes/computer-use/fanout-records.js +10 -11
- package/dist/routes/computer-use/live-flush.d.ts +1 -1
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +4 -2
- package/dist/routes/computer-use/live-phase.js +6 -6
- package/dist/routes/computer-use/local-vm.js +1 -1
- package/dist/routes/computer-use/participant-desktop.d.ts +4 -4
- package/dist/routes/computer-use/participant-desktop.js +4 -4
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +9 -9
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +31 -13
- package/dist/routes/computer-use/participant-prompt.d.ts +11 -11
- package/dist/routes/computer-use/participant-prompt.js +6 -6
- package/dist/routes/computer-use/participant-runs.d.ts +7 -7
- package/dist/routes/computer-use/participant-runs.js +13 -13
- package/dist/routes/computer-use/plan.js +22 -22
- package/dist/routes/computer-use/preflight.js +21 -21
- package/dist/routes/computer-use/rerun-selection.js +1 -1
- package/dist/routes/computer-use/result.js +11 -11
- package/dist/routes/computer-use/route.d.ts +2 -1
- package/dist/routes/computer-use/route.js +15 -14
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +31 -31
- package/dist/routes/computer-use/setup.d.ts +1 -1
- package/dist/routes/computer-use/setup.js +17 -18
- package/dist/routes/computer-use/single-bundle.d.ts +7 -7
- package/dist/routes/computer-use/single-bundle.js +28 -30
- package/dist/routes/computer-use/subject-projection.d.ts +1 -1
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +40 -42
- package/dist/routes/computer-use/types.js +10 -10
- package/dist/routes/preview.d.ts +8 -2
- package/dist/routes/preview.js +8 -4
- package/dist/routes/scripted/bundle.d.ts +2 -2
- package/dist/routes/scripted/bundle.js +13 -12
- package/dist/routes/scripted/plan.d.ts +1 -1
- package/dist/routes/scripted/plan.js +9 -9
- package/dist/routes/scripted/result.js +5 -5
- package/dist/routes/scripted/route.js +5 -6
- package/dist/routes/scripted/scenario.js +2 -2
- package/dist/routes/scripted/setup.js +7 -7
- package/dist/routes/scripted/subject.js +1 -1
- package/dist/routes/scripted/surface-records.js +3 -3
- package/dist/routes/scripted/types.d.ts +3 -5
- package/dist/routes/scripted/types.js +1 -1
- package/dist/routes/shared-world/bundle-records.js +9 -8
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +40 -38
- package/dist/routes/shared-world/checkpoints.d.ts +1 -1
- package/dist/routes/shared-world/checkpoints.js +1 -1
- package/dist/routes/shared-world/comms.d.ts +5 -5
- package/dist/routes/shared-world/comms.js +14 -14
- package/dist/routes/shared-world/external-public.d.ts +4 -3
- package/dist/routes/shared-world/external-public.js +16 -12
- package/dist/routes/shared-world/handoff.d.ts +7 -6
- package/dist/routes/shared-world/handoff.js +65 -57
- package/dist/routes/shared-world/lobby-code.d.ts +2 -2
- package/dist/routes/shared-world/lobby-code.js +9 -9
- package/dist/routes/shared-world/participant-specs.d.ts +7 -6
- package/dist/routes/shared-world/participant-specs.js +31 -24
- package/dist/routes/shared-world/plan.js +7 -7
- package/dist/routes/shared-world/provenance.d.ts +2 -2
- package/dist/routes/shared-world/provenance.js +2 -2
- package/dist/routes/shared-world/provisioned.js +14 -13
- package/dist/routes/shared-world/result.js +20 -21
- package/dist/routes/shared-world/route.js +23 -22
- package/dist/routes/shared-world/setup.d.ts +3 -3
- package/dist/routes/shared-world/setup.js +4 -4
- package/dist/routes/shared-world/types.d.ts +30 -28
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +3 -3
- package/dist/routes/terminal/adapter.js +5 -5
- package/dist/routes/terminal/bundle.d.ts +3 -3
- package/dist/routes/terminal/bundle.js +22 -21
- package/dist/routes/terminal/credentials.d.ts +4 -4
- package/dist/routes/terminal/credentials.js +7 -7
- package/dist/routes/terminal/dry-run.js +4 -4
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +3 -3
- package/dist/routes/terminal/ledger.js +14 -14
- package/dist/routes/terminal/live-finish.js +3 -3
- package/dist/routes/terminal/live-sandbox.js +12 -13
- package/dist/routes/terminal/persona.js +1 -1
- package/dist/routes/terminal/plan.js +11 -11
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.js +8 -8
- package/dist/routes/terminal/route.js +6 -7
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.js +8 -7
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +7 -8
- package/dist/routes/terminal/trace.d.ts +2 -2
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +26 -28
- package/dist/routes/terminal/types.js +3 -3
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +46 -46
- package/dist/run/bundle.js +2 -1
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.js +7 -1
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.js +1 -1
- package/dist/run/dry-run.js +18 -18
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +20 -13
- package/dist/run/projection.d.ts +14 -14
- package/dist/run/projection.js +15 -15
- package/dist/run/reclaim.js +2 -2
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-index.d.ts +8 -6
- package/dist/run/run-index.js +15 -16
- package/dist/run/run-not-found.d.ts +5 -0
- package/dist/run/run-not-found.js +15 -0
- package/dist/run/run.d.ts +5 -4
- package/dist/run/run.js +1 -1
- package/dist/run/sandbox-receipts.d.ts +2 -2
- package/dist/run/sandbox-receipts.js +3 -3
- package/dist/run/shared-world-evidence.d.ts +36 -35
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +1 -1
- package/dist/run/shared-world-shape.js +6 -6
- package/dist/run/stats.d.ts +12 -6
- package/dist/run/stats.js +116 -58
- package/dist/run/status.d.ts +8 -29
- package/dist/run/status.js +5 -27
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +6 -6
- package/dist/run/study-provenance.d.ts +47 -0
- package/dist/run/study-provenance.js +63 -0
- package/dist/run/study-result.d.ts +16 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run-lab.d.ts +7 -7
- package/dist/run-lab.js +1 -3
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- package/dist/study/field-paths.d.ts +12 -0
- package/dist/study/field-paths.js +126 -0
- package/dist/study/files.d.ts +26 -0
- package/dist/study/files.js +43 -0
- package/dist/study/migrate.d.ts +48 -0
- package/dist/study/migrate.js +408 -0
- package/dist/study/owned-files.d.ts +38 -0
- package/dist/study/owned-files.js +182 -0
- package/dist/subject/clone.d.ts +1 -1
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.js +1 -1
- package/dist/subject/local-tree.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +8 -9
- package/dist/subject/serve.d.ts +1 -1
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +1 -1
- package/dist/subject/steps.d.ts +5 -5
- package/dist/subject/steps.js +4 -4
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
- package/dist/substrates/e2b/cdp-probe.js +14 -17
- package/dist/substrates/e2b/desktop-browser.d.ts +2 -2
- package/dist/substrates/e2b/desktop-browser.js +8 -8
- package/dist/substrates/e2b/desktop-cdp.d.ts +9 -9
- package/dist/substrates/e2b/desktop-cdp.js +8 -8
- package/dist/substrates/e2b/desktop-executor.d.ts +1 -1
- package/dist/substrates/e2b/desktop-executor.js +1 -1
- package/dist/substrates/e2b/desktop-geometry.d.ts +3 -3
- package/dist/substrates/e2b/desktop-geometry.js +7 -7
- package/dist/substrates/e2b/desktop-media.d.ts +1 -1
- package/dist/substrates/e2b/desktop-media.js +1 -1
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
- package/dist/substrates/e2b/sandbox.d.ts +1 -1
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.d.ts +11 -11
- package/dist/substrates/e2b/sdk.js +6 -6
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +16 -16
- package/dist/tui/contract.js +10 -10
- package/dist/tui/launch.d.ts +4 -4
- package/dist/tui/launch.js +18 -19
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +82 -82
- package/dist/verify/actor.d.ts +8 -8
- package/dist/verify/actor.js +36 -36
- package/dist/verify/artifacts.d.ts +2 -2
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +6 -6
- package/dist/verify/costs.js +8 -8
- package/dist/verify/shared-world-concurrent.d.ts +2 -2
- package/dist/verify/shared-world-concurrent.js +79 -76
- package/dist/verify/shared-world.d.ts +2 -2
- package/dist/verify/shared-world.js +16 -16
- package/dist/verify/subject.d.ts +4 -4
- package/dist/verify/subject.js +18 -18
- package/dist/verify/verify.js +92 -43
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +56 -87
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +61 -59
- package/docs/architecture/github-feedback-loop.md +1 -4
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +34 -34
- package/docs/architecture/restricted-codex-analysis.md +34 -28
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -58
- package/docs/architecture/task-protocol-support.md +5 -5
- package/docs/architecture/terminal-product-route.md +67 -107
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +2 -5
- package/docs/contracts/core.md +1 -3
- package/docs/contracts/errors.md +62 -0
- package/docs/contracts/feedback.md +8 -9
- package/docs/contracts/policy.md +7 -12
- package/docs/contracts/run-bundle.md +45 -44
- package/docs/contracts/schemas.md +421 -362
- package/docs/contracts/study-analysis.md +3 -3
- package/docs/contracts/study-costs.md +11 -7
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
- package/docs/principles/actor-fidelity.md +4 -4
- package/docs/principles/engineering.md +3 -3
- package/docs/principles/invariants-and-defaults.md +38 -38
- package/docs/principles/self-driving-harness.md +1 -5
- package/docs/principles/three-roles.md +1 -1
- package/docs/product/automatic-analysis.md +7 -7
- package/examples/participant/README.md +5 -5
- package/examples/participant/run.mjs +11 -10
- package/examples/scorer/README.md +3 -3
- package/examples/scorer/run.mjs +11 -12
- package/package.json +16 -17
- package/skills/humanish/SKILL.md +60 -58
- package/skills/humanish/agents/openai.yaml +1 -1
- package/AGENTS.md +0 -99
- package/CONTRIBUTING.md +0 -148
- package/dist/actors/codex/qualified-versions.d.ts +0 -72
- package/dist/actors/codex/qualified-versions.js +0 -132
- package/dist/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -199
- package/dist/cli/renamed-options.d.ts +0 -11
- package/dist/cli/renamed-options.js +0 -18
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/docs/architecture/comms-inbox.md +0 -122
- package/docs/architecture/desktop-recording.md +0 -80
- package/docs/architecture/local-browser-runtime.md +0 -178
- package/docs/architecture/observer-review.md +0 -144
- package/docs/architecture/participant-media.md +0 -90
- package/docs/architecture/project-layout.md +0 -62
- package/docs/architecture/real-email-receiving.md +0 -136
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/assets/humanish-observer-hero.png +0 -0
- package/docs/goals/current.md +0 -207
- package/docs/product/lobby-trivia-3player-external-public.md +0 -77
- package/docs/product/open-source-install-experience.md +0 -240
- package/docs/ramp/README.md +0 -295
- package/docs/release/open-source-readiness.md +0 -222
- package/docs/release/public-readiness-standard.md +0 -210
- package/docs/roadmap/world-class-open-source-v0.md +0 -311
package/dist/lab/validation.js
CHANGED
|
@@ -2,28 +2,29 @@ import { isMaxOutputTokens } from "../actors/output-token-limit.js";
|
|
|
2
2
|
import { PARTICIPANT_ID_MAX_CHARS, PARTICIPANT_ID_PATTERN, focusOf, rosterOf, } from "./parse/actors.js";
|
|
3
3
|
import { isHttpUrl, isLoopbackUrl } from "./parse/subject.js";
|
|
4
4
|
import { declaredTargets } from "./plan-participants.js";
|
|
5
|
-
import { actorResolvesToComputerUse,
|
|
5
|
+
import { actorResolvesToComputerUse, computerUseParticipantCount, MAX_COMPUTER_USE_PARTICIPANTS, registeredComputerUseActors, resolveEntryUrl, isComputerUseComposition, isScriptedBrowserComposition, isSharedWorldComposition, isTerminalProductComposition, } from "./routing.js";
|
|
6
6
|
/**
|
|
7
7
|
* Cross-validate the computer-use fan-out declaration (`per-lane-worlds`). Returns the failure
|
|
8
|
-
* message, or null when valid.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* message, or null when valid. The parser enforces it, and runLab checks it again for a config
|
|
9
|
+
* that skipped the parser. It runs rosterStructuralValidationReason (id and device
|
|
10
|
+
* validity, unique ids) first, then the route-scoped XOR, cap and policy checks.
|
|
11
11
|
*/
|
|
12
|
-
export function
|
|
12
|
+
export function computerUseValidationReason(config) {
|
|
13
13
|
const actor = config.actors[0];
|
|
14
14
|
const roster = rosterOf(actor);
|
|
15
15
|
const structuralReason = rosterStructuralValidationReason(config);
|
|
16
16
|
if (structuralReason) {
|
|
17
17
|
return structuralReason;
|
|
18
18
|
}
|
|
19
|
-
// clone.fanout is a declared behavior change: rejected on the
|
|
20
|
-
// Fan-out is declared via `actors[0].count` or `actors[0].lanes`;
|
|
19
|
+
// clone.fanout is a declared behavior change: rejected on the computer-use route (was
|
|
20
|
+
// inert-warned). Fan-out is declared via `actors[0].count` or `actors[0].lanes`;
|
|
21
|
+
// subject.clone.fanout never applied here.
|
|
21
22
|
if (config.subject.clone?.fanout !== undefined) {
|
|
22
23
|
return "`subject.clone.fanout` is not used on the computer-use route: declare fan-out with actors[0].count (homogeneous) or actors[0].lanes (a roster of participants). (No current route reads clone.fanout.)";
|
|
23
24
|
}
|
|
24
25
|
if (roster !== undefined) {
|
|
25
26
|
if (actor?.count !== undefined) {
|
|
26
|
-
return "
|
|
27
|
+
return "Set either `actors[0].count` (identical participants) or `actors[0].lanes` (a roster of distinct participants), not both.";
|
|
27
28
|
}
|
|
28
29
|
if (focusOf(actor) !== undefined) {
|
|
29
30
|
return "actors[0].laneFocus and actors[0].lanes are mutually exclusive: each roster entry's `instruction` is the fan-out steer; laneFocus is the steer for a single participant.";
|
|
@@ -35,7 +36,7 @@ export function cuaLaneValidationReason(config) {
|
|
|
35
36
|
const targeted = roster.filter((entry) => entry.target !== undefined);
|
|
36
37
|
if (targeted.length > 0) {
|
|
37
38
|
if (config.subject.source !== "app-url") {
|
|
38
|
-
return "actors[0].lanes[].target
|
|
39
|
+
return "`actors[0].lanes[].target` works only on app-url computer-use studies. Clone, shared-world and local-app studies set each participant's entry URL themselves; remove `target`.";
|
|
39
40
|
}
|
|
40
41
|
if (roster.some((entry) => entry.entry !== undefined)) {
|
|
41
42
|
return "actors[0].lanes[].target and actors[0].lanes[].entry are mutually exclusive: target is an app-url fan-out browser URL; entry is a shared-world same-origin participant path.";
|
|
@@ -45,21 +46,21 @@ export function cuaLaneValidationReason(config) {
|
|
|
45
46
|
}
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
const participantCount =
|
|
49
|
-
if (participantCount >
|
|
50
|
-
return `
|
|
49
|
+
const participantCount = computerUseParticipantCount(config);
|
|
50
|
+
if (participantCount > MAX_COMPUTER_USE_PARTICIPANTS) {
|
|
51
|
+
return `A computer-use study runs at most ${MAX_COMPUTER_USE_PARTICIPANTS} participants, and this one declares ${participantCount}. Each participant is a paid desktop and they all run at once, so no setting raises the cap; split the roster across studies.`;
|
|
51
52
|
}
|
|
52
53
|
// Public targets fan out into N independent worlds driving the same public app, which is an
|
|
53
54
|
// ambiguous shared-world-ish shape, not a per-participant target swarm. Permit N>1 public runs only
|
|
54
55
|
// when every roster entry declares its own target, making the adapter-owned topology explicit. But when
|
|
55
56
|
// `subject.topology: shared-world` is also declared, N participants against one public target is the
|
|
56
|
-
// external-public shared-world topology
|
|
57
|
+
// external-public shared-world topology, so route it there (a real public deployment
|
|
57
58
|
// as the shared plane) instead of refusing; externalPublicSharedWorldValidationReason then applies.
|
|
58
59
|
if (participantCount > 1 &&
|
|
59
60
|
config.policies?.allowPublicTargets === true &&
|
|
60
61
|
declaredTargets(config).length === 0 &&
|
|
61
62
|
config.subject.topology !== "shared-world") {
|
|
62
|
-
return "policies.allowPublicTargets
|
|
63
|
+
return "`policies.allowPublicTargets` with more than one participant sends them all to one public app, which is a shared world. Set `subject.topology: shared-world` to run them together there, give each `actors[0].lanes[]` entry its own `target`, or run one participant.";
|
|
63
64
|
}
|
|
64
65
|
return null;
|
|
65
66
|
}
|
|
@@ -96,10 +97,10 @@ function rosterStructuralValidationReason(config) {
|
|
|
96
97
|
return null;
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
99
|
-
* Cross-validate a `topology: shared-world` declaration
|
|
100
|
+
* Cross-validate a `topology: shared-world` declaration. Returns the failure message, or
|
|
100
101
|
* null when the one shared-world route can run it: the external-public checks for an app-url
|
|
101
102
|
* subject, the provisioned checks otherwise. Enforced at parse and again by the route, since
|
|
102
|
-
*
|
|
103
|
+
* runLab takes a config that skipped the parser.
|
|
103
104
|
*/
|
|
104
105
|
export function sharedWorldValidationReason(config) {
|
|
105
106
|
return config.subject.source === "app-url"
|
|
@@ -119,7 +120,7 @@ function provisionedSharedWorldStructureReason(config) {
|
|
|
119
120
|
return structuralReason;
|
|
120
121
|
}
|
|
121
122
|
if (config.subject.source !== "clone" && config.subject.source !== "local-tree") {
|
|
122
|
-
return "`subject.topology: shared-world`
|
|
123
|
+
return "`subject.topology: shared-world` needs `subject.source: clone` or `local-tree`, which humanish serves as one seeded app every participant uses, or `app-url` for a public deployment you own.";
|
|
123
124
|
}
|
|
124
125
|
if (config.execution?.target !== "e2b-desktop") {
|
|
125
126
|
return "`subject.topology: shared-world` requires `execution.target: e2b-desktop`: the role participants drive hosted desktop browsers against one in-sandbox app.";
|
|
@@ -129,17 +130,17 @@ function provisionedSharedWorldStructureReason(config) {
|
|
|
129
130
|
}
|
|
130
131
|
const serve = config.subject.serve;
|
|
131
132
|
if (!serve) {
|
|
132
|
-
return "`subject.topology: shared-world`
|
|
133
|
+
return "`subject.topology: shared-world` needs `subject.serve` (start and url): humanish starts one copy of the app in the sandbox, and every participant uses it.";
|
|
133
134
|
}
|
|
134
135
|
const roster = rosterOf(config.actors[0]);
|
|
135
136
|
if (!roster || roster.length < 2) {
|
|
136
|
-
return "`subject.topology: shared-world`
|
|
137
|
+
return "`subject.topology: shared-world` needs an `actors[0].lanes` roster of at least 2 participants: with one participant there is nobody to interact with.";
|
|
137
138
|
}
|
|
138
139
|
if (!config.subject.state?.checkpoint || config.subject.state.checkpoint.length === 0) {
|
|
139
|
-
return "`subject.topology: shared-world`
|
|
140
|
+
return "`subject.topology: shared-world` needs at least one read-only `subject.state.checkpoint` probe: the checkpoints are how the run shows that participants changed the shared app.";
|
|
140
141
|
}
|
|
141
142
|
for (const entry of roster) {
|
|
142
|
-
if (entry.entry !== undefined &&
|
|
143
|
+
if (entry.entry !== undefined && resolveEntryUrl(serve.url, entry.entry) === null) {
|
|
143
144
|
return `actors[0].lanes role "${entry.id ?? "(unnamed)"}".entry must resolve same-origin (loopback) with subject.serve.url (${serve.url}); got "${entry.entry}".`;
|
|
144
145
|
}
|
|
145
146
|
}
|
|
@@ -198,7 +199,7 @@ export function receivingEmailValidationReason(config) {
|
|
|
198
199
|
}
|
|
199
200
|
return undefined;
|
|
200
201
|
}
|
|
201
|
-
/** Refuse task declarations that the selected execution path would discard
|
|
202
|
+
/** Refuse task declarations that the selected execution path would discard.
|
|
202
203
|
* Direct runners pass their actual support rather than trusting the config's dispatch shape. */
|
|
203
204
|
export function taskProtocolValidationReason(config, supportsTasks = isComputerUseComposition(config) && !isSharedWorldComposition(config)) {
|
|
204
205
|
for (const [index, actor] of config.actors.entries()) {
|
|
@@ -263,7 +264,8 @@ export function outputTokenLimitValidationReason(config) {
|
|
|
263
264
|
* Shared-world participants share one live app, so at least two must be live at once. The
|
|
264
265
|
* sequential shared-world route (`execution.concurrency: 1`) was removed in 0.106.0; the parser
|
|
265
266
|
* fills an omitted concurrency with the participant count. Both callers check it after their
|
|
266
|
-
* two-participant roster floor, so a one-
|
|
267
|
+
* two-participant roster floor, so a one-participant roster gets the roster refusal, never this
|
|
268
|
+
* one.
|
|
267
269
|
*/
|
|
268
270
|
function sharedWorldConcurrencyReason(config) {
|
|
269
271
|
// Direct library callers skip the parser, so an omitted value defaults here exactly as the
|
|
@@ -275,12 +277,12 @@ function sharedWorldConcurrencyReason(config) {
|
|
|
275
277
|
return `shared-world labs need \`execution.concurrency\` of at least 2 (got ${concurrency}). Sequential shared-world turns (concurrency 1) were removed in 0.106.0: omit execution.concurrency to run every participant at once, or set it to 2 or more. A provisioned subject also needs \`subject.exposure: synthetic\` and a \`serve.start\` that binds 0.0.0.0.`;
|
|
276
278
|
}
|
|
277
279
|
/**
|
|
278
|
-
* Cross-validate a concurrent shared-world declaration
|
|
280
|
+
* Cross-validate a concurrent shared-world declaration. Returns the failure message,
|
|
279
281
|
* or null when valid. Includes the base shared-world checks plus the concurrent extras: a synthetic
|
|
280
282
|
* subject attestation, a 0.0.0.0 serve bind (getHost only routes to a port bound on
|
|
281
283
|
* all interfaces), and no `subject.clone.keep`/`subject.localTree.keep` (either would
|
|
282
|
-
* orphan actor sandboxes). Enforced at parse and re-enforced in the engine (
|
|
283
|
-
*
|
|
284
|
+
* orphan actor sandboxes). Enforced at parse and re-enforced in the engine (runLab
|
|
285
|
+
* takes a config that skipped the parser).
|
|
284
286
|
*/
|
|
285
287
|
export function concurrentSharedWorldValidationReason(config) {
|
|
286
288
|
const base = provisionedSharedWorldStructureReason(config);
|
|
@@ -291,11 +293,11 @@ export function concurrentSharedWorldValidationReason(config) {
|
|
|
291
293
|
if (sharedWorldConcurrency)
|
|
292
294
|
return sharedWorldConcurrency;
|
|
293
295
|
if (config.subject.exposure !== "synthetic") {
|
|
294
|
-
return "
|
|
296
|
+
return "A shared-world study needs `subject.exposure: synthetic`. The subject is reachable from the internet at a public sandbox URL during the run, so the study must declare that its data is synthetic and seeded.";
|
|
295
297
|
}
|
|
296
298
|
const serve = config.subject.serve;
|
|
297
299
|
if (!serve || !serve.start.includes("0.0.0.0")) {
|
|
298
|
-
return "
|
|
300
|
+
return "A shared-world study needs `subject.serve.start` to listen on all interfaces (for example `-H 0.0.0.0`, `--host 0.0.0.0` or `HOST=0.0.0.0`): the public sandbox URL reaches only a port bound to 0.0.0.0, and a loopback-only server answers 502. The readiness probe still uses loopback.";
|
|
299
301
|
}
|
|
300
302
|
if (config.subject.clone?.keep === true || config.subject.localTree?.keep === true) {
|
|
301
303
|
const keepField = config.subject.clone?.keep === true ? "subject.clone.keep" : "subject.localTree.keep";
|
|
@@ -304,15 +306,15 @@ export function concurrentSharedWorldValidationReason(config) {
|
|
|
304
306
|
return null;
|
|
305
307
|
}
|
|
306
308
|
/**
|
|
307
|
-
* Cross-validate the external-public shared-world declaration
|
|
309
|
+
* Cross-validate the external-public shared-world declaration: a real public
|
|
308
310
|
* deployment used directly as the shared plane (no getHost, no clone, no subject sandbox, no seed).
|
|
309
311
|
* The counterpart of concurrentSharedWorldValidationReason for a plane the harness does not own:
|
|
310
312
|
* it rejects every provisioned-subject field (serve/state.seed/state.checkpoint/exposure/clone/repos
|
|
311
|
-
* are inert with no sandbox, so they fail closed
|
|
313
|
+
* are inert with no sandbox, so they fail closed), and requires a
|
|
312
314
|
* non-loopback appUrl + allowPublicTargets + the operator-ownership attestation subject.publicTarget +
|
|
313
315
|
* concurrency >= 2 + an actors[0].lanes roster of ≥2 with exactly one host participant. The getHost synthetic
|
|
314
316
|
* gate is deliberately unreachable here (there is no internet-reachable harness-owned URL to attest).
|
|
315
|
-
* Enforced at parse and re-enforced in the engine (
|
|
317
|
+
* Enforced at parse and re-enforced in the engine (runLab takes a config that skipped the parser).
|
|
316
318
|
*/
|
|
317
319
|
export function externalPublicSharedWorldValidationReason(config) {
|
|
318
320
|
const structuralReason = rosterStructuralValidationReason(config);
|
|
@@ -320,7 +322,7 @@ export function externalPublicSharedWorldValidationReason(config) {
|
|
|
320
322
|
return structuralReason;
|
|
321
323
|
}
|
|
322
324
|
if (config.subject.source !== "app-url") {
|
|
323
|
-
return "
|
|
325
|
+
return "An external-public shared-world study needs `subject.source: app-url`: the participants share a public deployment you already run, so there is nothing to clone or serve.";
|
|
324
326
|
}
|
|
325
327
|
if (config.execution?.target !== "e2b-desktop") {
|
|
326
328
|
return "the external-public shared-world route requires `execution.target: e2b-desktop`: the role participants drive hosted desktop browsers against the one public deployment.";
|
|
@@ -336,40 +338,40 @@ export function externalPublicSharedWorldValidationReason(config) {
|
|
|
336
338
|
if (sharedWorldConcurrency)
|
|
337
339
|
return sharedWorldConcurrency;
|
|
338
340
|
if (config.policies?.allowPublicTargets !== true) {
|
|
339
|
-
return "
|
|
341
|
+
return "An external-public shared-world study needs `policies.allowPublicTargets: true`, because the participants drive a public deployment.";
|
|
340
342
|
}
|
|
341
343
|
const appUrl = config.subject.appUrl ?? "";
|
|
342
344
|
if (!isHttpUrl(appUrl) || isLoopbackUrl(appUrl)) {
|
|
343
|
-
return "
|
|
345
|
+
return "An external-public shared-world study needs a public http(s) `subject.appUrl`, not a loopback URL. For an app you run locally, use a clone or local-tree subject, which humanish serves itself.";
|
|
344
346
|
}
|
|
345
|
-
// The operator-ownership attestation (the
|
|
347
|
+
// The operator-ownership attestation (the counterpart of exposure: synthetic; you cannot claim
|
|
346
348
|
// synthetic on a real site, but you must attest you own/operate it). Author-trust; unverifiable.
|
|
347
349
|
if (config.subject.publicTarget?.authorized !== true) {
|
|
348
|
-
return "
|
|
350
|
+
return "An external-public shared-world study needs `subject.publicTarget: { owner, authorized: true }` to declare that you own or operate the public deployment. humanish cannot check ownership, so the study states it.";
|
|
349
351
|
}
|
|
350
352
|
// No provisioned-subject field is allowed: with no sandbox they cannot act, so they are rejected
|
|
351
|
-
// with a precise reason, never silently ignored
|
|
353
|
+
// with a precise reason, never silently ignored. exposure: synthetic in particular
|
|
352
354
|
// would be a false claim on a real site (the harness neither provisioned nor exposed it).
|
|
353
355
|
if (config.subject.exposure !== undefined) {
|
|
354
|
-
return "`subject.exposure: synthetic`
|
|
356
|
+
return "`subject.exposure: synthetic` does not apply to an external-public shared-world study: a real public deployment is not seeded synthetic data. Declare ownership with `subject.publicTarget` instead.";
|
|
355
357
|
}
|
|
356
358
|
if (config.subject.serve !== undefined) {
|
|
357
|
-
return "`subject.serve`
|
|
359
|
+
return "`subject.serve` does not apply to an external-public shared-world study: the app is already deployed, so humanish serves nothing. Remove `subject.serve`.";
|
|
358
360
|
}
|
|
359
361
|
if (config.subject.state?.seed !== undefined ||
|
|
360
362
|
config.subject.state?.checkpoint !== undefined ||
|
|
361
363
|
config.subject.state !== undefined) {
|
|
362
|
-
return "`subject.state` (seed
|
|
364
|
+
return "`subject.state` (seed, checkpoint or external) does not apply to an external-public shared-world study: humanish cannot seed or read a deployment it does not run. Remove `subject.state`.";
|
|
363
365
|
}
|
|
364
366
|
if (config.subject.clone !== undefined || config.subject.repos !== undefined) {
|
|
365
|
-
return "`subject.clone
|
|
367
|
+
return "`subject.clone` and `subject.repos` do not apply to an external-public shared-world study: the participants use the public deployment, so nothing is cloned. Remove them.";
|
|
366
368
|
}
|
|
367
369
|
if (roster.some((entry) => entry.entry !== undefined)) {
|
|
368
370
|
return "`actors[0].lanes[].entry` (the loopback same-origin participant path) is forbidden on the external-public shared-world route: there is no harness-served serve.url to resolve it against; participants open the public appUrl and reach the shared session through the real UI.";
|
|
369
371
|
}
|
|
370
372
|
const hostEntries = roster.filter((entry) => entry.host === true);
|
|
371
373
|
if (hostEntries.length !== 1) {
|
|
372
|
-
return `
|
|
374
|
+
return `An external-public shared-world study needs exactly one \`host: true\` participant, the one who creates the shared session, and this study has ${hostEntries.length}. Every other participant joins that session.`;
|
|
373
375
|
}
|
|
374
376
|
return null;
|
|
375
377
|
}
|
package/dist/lab/warnings.d.ts
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
import type { LabConfig } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The fields a config sets that its route does not read, each as `field` or `field (reason)`. A v2
|
|
4
|
+
* file gets them as one warning; a v3 study is refused for any of them.
|
|
5
|
+
*/
|
|
6
|
+
export declare function inertFieldLabels(config: LabConfig): string[];
|
|
7
|
+
/**
|
|
8
|
+
* The same fields as `inertFieldLabels`, as paths without their reasons, such as
|
|
9
|
+
* `actors[0].lanes[].entry` or `execution.timeoutMs`. `humanish migrate` drops each one.
|
|
10
|
+
*/
|
|
11
|
+
export declare function inertFieldPaths(config: LabConfig): string[];
|
|
2
12
|
export declare function forwardDeclaredWarnings(config: LabConfig): string[];
|
package/dist/lab/warnings.js
CHANGED
|
@@ -13,13 +13,13 @@ const otherRoute = (routes) => !promptRoute(routes) && !routes.scripted;
|
|
|
13
13
|
/** Rows for each actor, reported as `actors[<index>].<field>`, in this order per actor. */
|
|
14
14
|
const ACTOR_ROWS = [
|
|
15
15
|
// Shared-world-only fields on the roster: a participant's `entry` is inert anywhere else
|
|
16
|
-
// (
|
|
16
|
+
// (claims match mechanism).
|
|
17
17
|
{
|
|
18
18
|
field: "lanes[].entry",
|
|
19
19
|
reason: "the per-participant loopback entry is a shared-world capability; needs subject.topology: shared-world",
|
|
20
20
|
applies: (actor, routes) => Boolean(rosterOf(actor)?.some((entry) => entry.entry !== undefined)) && !routes.shared,
|
|
21
21
|
},
|
|
22
|
-
// The host
|
|
22
|
+
// The host marker acts only on the external-public shared-world route; inert elsewhere.
|
|
23
23
|
{
|
|
24
24
|
field: "lanes[].host",
|
|
25
25
|
reason: "the designated host-participant marker; needs the external-public shared-world route: app-url × topology shared-world × allowPublicTargets",
|
|
@@ -35,7 +35,7 @@ const ACTOR_ROWS = [
|
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
field: "lanes",
|
|
38
|
-
reason: "
|
|
38
|
+
reason: "only the computer-use route runs more than one participant",
|
|
39
39
|
applies: (actor, routes) => routes.terminal && Boolean(rosterOf(actor)),
|
|
40
40
|
},
|
|
41
41
|
{
|
|
@@ -69,7 +69,7 @@ const ACTOR_ROWS = [
|
|
|
69
69
|
{ field: "lanes", applies: (actor, routes) => otherRoute(routes) && Boolean(rosterOf(actor)) },
|
|
70
70
|
];
|
|
71
71
|
const TERMINAL_ONLY = "needs subject.source: terminal-product + a registered terminal actor";
|
|
72
|
-
const RESERVED = "reserved
|
|
72
|
+
const RESERVED = "reserved; no route reads it yet";
|
|
73
73
|
/** Rows for the rest of the config, reported after the actor rows, in this order. */
|
|
74
74
|
const CONFIG_ROWS = [
|
|
75
75
|
// The computer-use routes consume (clone) subject.{serve,env,state,clone.depth}, and so does the
|
|
@@ -90,8 +90,9 @@ const CONFIG_ROWS = [
|
|
|
90
90
|
field: "subject.state",
|
|
91
91
|
applies: (config, routes) => Boolean(config.subject.state) && !routes.cua && !routes.scripted,
|
|
92
92
|
},
|
|
93
|
-
// topology + checkpoint act only on the shared-world route
|
|
94
|
-
// (incl. an explicit per-lane-worlds, which the
|
|
93
|
+
// topology + checkpoint act only on the shared-world route; a set-but-unconsumed value
|
|
94
|
+
// (incl. an explicit per-lane-worlds, which the computer-use route already is by mechanism) warns
|
|
95
|
+
// inert.
|
|
95
96
|
{
|
|
96
97
|
field: "subject.topology",
|
|
97
98
|
reason: "drives behavior only on the shared-world route; needs subject.topology: shared-world + clone × e2b-desktop × a computer-use actor + a roster of ≥2 participants",
|
|
@@ -113,7 +114,7 @@ const CONFIG_ROWS = [
|
|
|
113
114
|
// getHost-exposed plane) and on scripted clones; inert elsewhere.
|
|
114
115
|
{
|
|
115
116
|
field: "subject.exposure",
|
|
116
|
-
reason: "the
|
|
117
|
+
reason: "the statement that a subject served on a public sandbox URL holds only synthetic data; needs shared-world or clone × e2b-desktop × scripted-browser",
|
|
117
118
|
applies: (config, routes) => config.subject.exposure !== undefined &&
|
|
118
119
|
!routes.shared &&
|
|
119
120
|
!(routes.scripted && config.subject.source === "clone"),
|
|
@@ -121,10 +122,10 @@ const CONFIG_ROWS = [
|
|
|
121
122
|
// comms.email drives the in-sandbox email/SMS catch, which needs a subject sandbox that humanish
|
|
122
123
|
// provisions (clone or local-tree) so it holds a handle to host the catch. On an app-url /
|
|
123
124
|
// operator-provided subject there is no such handle, so a declared comms block would silently
|
|
124
|
-
// collect nothing
|
|
125
|
+
// collect nothing, a false green. Warn at parse time (fires on inspect + dry-run too).
|
|
125
126
|
{
|
|
126
127
|
field: "comms.email",
|
|
127
|
-
reason: "the
|
|
128
|
+
reason: "the email catch runs in a sandbox humanish provisions, which needs `subject.source: clone` or `local-tree`, and an app-url subject has none. To use email here, run the catch yourself with `humanish comms catch` and declare `comms.email.external`: humanish then points each persona at your inbox, reads your catch and records the same evidence",
|
|
128
129
|
applies: (config) => config.comms?.email?.kind === "fake" &&
|
|
129
130
|
config.comms.email.external === undefined &&
|
|
130
131
|
config.subject.source !== "clone" &&
|
|
@@ -139,9 +140,9 @@ const CONFIG_ROWS = [
|
|
|
139
140
|
applies: (config) => Boolean(config.comms?.email?.external) &&
|
|
140
141
|
(config.subject.source === "clone" || config.subject.source === "local-tree"),
|
|
141
142
|
},
|
|
142
|
-
// clone.keep is consumed on the
|
|
143
|
-
// a failed install/boot; otherwise always killed). clone.fanout is rejected on the
|
|
144
|
-
// (a hard parse error above), so it can never reach this warning list there.
|
|
143
|
+
// clone.keep is consumed on the computer-use route (honored on failure: the sandbox is left up to
|
|
144
|
+
// debug a failed install/boot; otherwise always killed). clone.fanout is rejected on the
|
|
145
|
+
// computer-use route (a hard parse error above), so it can never reach this warning list there.
|
|
145
146
|
{
|
|
146
147
|
field: "execution.timeoutMs",
|
|
147
148
|
applies: (config, routes) => !routes.cua &&
|
|
@@ -153,23 +154,24 @@ const CONFIG_ROWS = [
|
|
|
153
154
|
field: "execution.completionTimeoutMs",
|
|
154
155
|
applies: (config) => config.execution?.completionTimeoutMs !== undefined,
|
|
155
156
|
},
|
|
156
|
-
// execution.concurrency is consumed on the
|
|
157
|
-
// inert (warned) everywhere else.
|
|
157
|
+
// execution.concurrency is consumed on the computer-use route (it bounds in-flight fan-out
|
|
158
|
+
// participants); inert (warned) everywhere else.
|
|
158
159
|
{
|
|
159
160
|
field: "execution.concurrency",
|
|
160
161
|
applies: (config, routes) => config.execution?.concurrency !== undefined && !routes.cua,
|
|
161
162
|
},
|
|
162
|
-
// execution.caps is consumed on the
|
|
163
|
-
// (warned) everywhere else so a misplaced budget field is never trusted to cap a route it
|
|
163
|
+
// execution.caps is consumed on the computer-use route (maxUsd is the fail-closed spend abort);
|
|
164
|
+
// inert (warned) everywhere else so a misplaced budget field is never trusted to cap a route it
|
|
165
|
+
// cannot.
|
|
164
166
|
{
|
|
165
167
|
field: "execution.caps",
|
|
166
|
-
reason: "the
|
|
168
|
+
reason: "only the computer-use route enforces it, with a computer-use actor on e2b-desktop",
|
|
167
169
|
applies: (config, routes) => Boolean(config.execution?.caps) && !routes.cua,
|
|
168
170
|
},
|
|
169
171
|
// terminal-product consumes subject.product, scenario.caps, execution.{terminal,runtimeAuth}:
|
|
170
172
|
// dry-run records the contract; live execution enforces caps and command-scoped auth. On every
|
|
171
173
|
// other route they are inert and must warn so a
|
|
172
|
-
// misplaced safety/budget field is never trusted to do something it cannot
|
|
174
|
+
// misplaced safety/budget field is never trusted to do something it cannot.
|
|
173
175
|
{
|
|
174
176
|
field: "subject.product",
|
|
175
177
|
reason: "needs subject.source: terminal-product or desktop-cli with the matching actor",
|
|
@@ -229,9 +231,9 @@ const CONFIG_ROWS = [
|
|
|
229
231
|
applies: (config, routes) => !routes.cua && config.execution?.desktop?.sandboxTimeoutMs !== undefined,
|
|
230
232
|
},
|
|
231
233
|
// execution.desktop.template (the custom E2B desktop image) is consumed only where a desktop is
|
|
232
|
-
// actually created via Sandbox.create
|
|
233
|
-
// concurrent). It is inert on every other route (incl. the in-process local-app
|
|
234
|
-
// creates no desktop): warn so an unconsumed template is never silently ignored
|
|
234
|
+
// actually created via Sandbox.create: the e2b-desktop computer-use routes (cua/shared-world/
|
|
235
|
+
// concurrent). It is inert on every other route (incl. the in-process local-app computer-use
|
|
236
|
+
// route, which creates no desktop): warn so an unconsumed template is never silently ignored.
|
|
235
237
|
{
|
|
236
238
|
field: "execution.desktop.template",
|
|
237
239
|
reason: "the custom E2B desktop image is consumed only on execution.target: e2b-desktop computer-use routes that create a desktop; needs a computer-use actor on e2b-desktop",
|
|
@@ -251,8 +253,8 @@ const CONFIG_ROWS = [
|
|
|
251
253
|
applies: (config, routes) => Boolean(config.scenario?.ref) && !routes.scripted,
|
|
252
254
|
},
|
|
253
255
|
{ field: "scenario.inline", applies: (config) => Boolean(config.scenario?.inline) },
|
|
254
|
-
// review.{scoring,milestones,vocabulary} stay forward-declared
|
|
255
|
-
// review.scorer
|
|
256
|
+
// review.{scoring,milestones,vocabulary} stay forward-declared on every route.
|
|
257
|
+
// review.scorer is consumed (loaded + wired, or fail-closed at load) on every scorer-capable
|
|
256
258
|
// route, so it does not warn there; on the scripted-browser route the actor carries no scorer seam,
|
|
257
259
|
// so a declared scorer is flagged inert (the run also fails closed at load).
|
|
258
260
|
{
|
|
@@ -297,9 +299,11 @@ function rowLabel(row, prefix = "") {
|
|
|
297
299
|
? `${prefix}${row.field}`
|
|
298
300
|
: `${prefix}${row.field} (${row.reason})`;
|
|
299
301
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
302
|
+
/**
|
|
303
|
+
* The fields a config sets that its route does not read, each as `field` or `field (reason)`. A v2
|
|
304
|
+
* file gets them as one warning; a v3 study is refused for any of them.
|
|
305
|
+
*/
|
|
306
|
+
export function inertFieldLabels(config) {
|
|
303
307
|
const routes = routesOf(config);
|
|
304
308
|
const inert = [];
|
|
305
309
|
for (const [index, actor] of config.actors.entries()) {
|
|
@@ -310,14 +314,38 @@ export function forwardDeclaredWarnings(config) {
|
|
|
310
314
|
for (const row of CONFIG_ROWS)
|
|
311
315
|
if (row.applies(config, routes))
|
|
312
316
|
inert.push(rowLabel(row));
|
|
317
|
+
return inert;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* The same fields as `inertFieldLabels`, as paths without their reasons, such as
|
|
321
|
+
* `actors[0].lanes[].entry` or `execution.timeoutMs`. `humanish migrate` drops each one.
|
|
322
|
+
*/
|
|
323
|
+
export function inertFieldPaths(config) {
|
|
324
|
+
const routes = routesOf(config);
|
|
325
|
+
const paths = [];
|
|
326
|
+
for (const [index, actor] of config.actors.entries()) {
|
|
327
|
+
for (const row of ACTOR_ROWS)
|
|
328
|
+
if (row.applies(actor, routes))
|
|
329
|
+
paths.push(`actors[${index}].${row.field}`);
|
|
330
|
+
}
|
|
331
|
+
for (const row of CONFIG_ROWS)
|
|
332
|
+
if (row.applies(config, routes))
|
|
333
|
+
paths.push(row.field);
|
|
334
|
+
return paths;
|
|
335
|
+
}
|
|
336
|
+
// Report fields that are present but not yet consumed by the engine, so a user never trusts a
|
|
337
|
+
// setting that silently does nothing.
|
|
338
|
+
export function forwardDeclaredWarnings(config) {
|
|
339
|
+
const routes = routesOf(config);
|
|
340
|
+
const inert = inertFieldLabels(config);
|
|
313
341
|
const warnings = inert.length === 0
|
|
314
342
|
? []
|
|
315
343
|
: [
|
|
316
|
-
`
|
|
344
|
+
`These fields are set, but no route reads them yet, so they have no effect: ${inert.join(", ")}.`,
|
|
317
345
|
];
|
|
318
|
-
// A declared cap below the
|
|
319
|
-
// the cap delivers waves of M. Say so up front (inspect + dry-run + run)
|
|
320
|
-
// is otherwise indistinguishable from the all-live run the author meant
|
|
346
|
+
// A declared cap below the participant count is legal but loud: the roster promises N live actors
|
|
347
|
+
// and the cap delivers waves of M. Say so up front (inspect + dry-run + run): a green run in
|
|
348
|
+
// waves is otherwise indistinguishable from the all-live run the author meant.
|
|
321
349
|
{
|
|
322
350
|
const participantCount = rosterOf(config.actors[0])?.length ?? config.actors[0]?.count ?? 1;
|
|
323
351
|
const cap = config.execution?.concurrency;
|
|
@@ -325,14 +353,14 @@ export function forwardDeclaredWarnings(config) {
|
|
|
325
353
|
warnings.push(`execution.concurrency ${cap} caps a ${participantCount}-participant roster: participants run in waves of ${cap}, never all live at once. Remove execution.concurrency (the default runs all ${participantCount} participants simultaneously) or set it to ${participantCount}; declare a lower cap only to bound simultaneous paid desktops.`);
|
|
326
354
|
}
|
|
327
355
|
}
|
|
328
|
-
// Partial email coverage is legal but loud
|
|
329
|
-
// hears an inbox exists, so an email-gated flow on that
|
|
356
|
+
// Partial email coverage is legal but loud: a participant without an addressed recipient never
|
|
357
|
+
// hears an inbox exists, so an email-gated flow on that participant dead-ends by construction.
|
|
330
358
|
if (routes.cua && config.comms?.email?.recipients) {
|
|
331
359
|
const participantIds = declaredParticipantIds(config);
|
|
332
360
|
const covered = new Set(addressedRecipients(config.comms.email).map((recipient) => recipient.participantId));
|
|
333
361
|
const uncovered = participantIds.filter((id) => !covered.has(id));
|
|
334
362
|
if (covered.size > 0 && uncovered.length > 0 && participantIds.length > 1) {
|
|
335
|
-
warnings.push(`comms.email covers ${covered.size} of ${participantIds.length} participants
|
|
363
|
+
warnings.push(`comms.email covers ${covered.size} of ${participantIds.length} participants. These get no inbox and are never told one exists: ${uncovered.join(", ")}. Add a recipient with an address for each one whose flow needs email.`);
|
|
336
364
|
}
|
|
337
365
|
}
|
|
338
366
|
return warnings;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CuaAdmissionLimitError as AdmissionLimitError } from "./actors/computer-use/admission-limit.js";
|
|
2
|
+
import type { CuaAction as Action, CuaExecutor as Executor, CuaLoopOptions as LoopOptions, CuaLoopResult as LoopResult, CuaObservation as Observation, CuaProvider as Provider, CuaSafetyCheck as SafetyCheck, CuaTurn as Turn, CuaTurnRequest as TurnRequest } from "./actors/computer-use/loop.js";
|
|
3
|
+
import type { BrowserLabScoringContext as BrowserScoringContext } from "./lab/adapter-extension.js";
|
|
4
|
+
import { parseLabConfig as parseStudy } from "./lab/config.js";
|
|
5
|
+
import type { LabRoute as StudyRoute } from "./lab/routing.js";
|
|
6
|
+
import type { LabEvent as StudyEvent } from "./lab/run-lab-events.js";
|
|
7
|
+
import { type LabConfig as StudyConfig } from "./lab/types.js";
|
|
8
|
+
import { runPackageLab as runStudy, type LabOutcome as StudyOutcome, type LabResult as StudyResult, type RunLabOptions as RunStudyOptions } from "./run-lab.js";
|
|
9
|
+
/** @deprecated Use `runStudy`, the same function. 0.109 removes `runLab`. */
|
|
10
|
+
export declare const runLab: typeof runStudy;
|
|
11
|
+
/** @deprecated Use `parseStudy`, the same function. 0.109 removes `parseLabConfig`. */
|
|
12
|
+
export declare const parseLabConfig: typeof parseStudy;
|
|
13
|
+
/**
|
|
14
|
+
* The `humanish.lab.v2` schema id, which 0.109 stops parsing.
|
|
15
|
+
* @deprecated Write `STUDY_SCHEMA` (`humanish.study.v3`) files. 0.109 removes `LAB_CONFIG_SCHEMA`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const LAB_CONFIG_SCHEMA = "humanish.lab.v2";
|
|
18
|
+
/** @deprecated Use `StudyConfig`, the same type. 0.109 removes `LabConfig`. */
|
|
19
|
+
export type LabConfig = StudyConfig;
|
|
20
|
+
/** @deprecated Use `StudyEvent`, the same type. 0.109 removes `LabEvent`. */
|
|
21
|
+
export type LabEvent = StudyEvent;
|
|
22
|
+
/** @deprecated Use `StudyOutcome`, the same type. 0.109 removes `LabOutcome`. */
|
|
23
|
+
export type LabOutcome = StudyOutcome;
|
|
24
|
+
/** @deprecated Use `StudyResult`, the same type. 0.109 removes `LabResult`. */
|
|
25
|
+
export type LabResult<R extends StudyRoute = StudyRoute> = StudyResult<R>;
|
|
26
|
+
/** @deprecated Use `StudyRoute`, the same type. 0.109 removes `LabRoute`. */
|
|
27
|
+
export type LabRoute = StudyRoute;
|
|
28
|
+
/** @deprecated Use `RunStudyOptions`, the same type. 0.109 removes `RunLabOptions`. */
|
|
29
|
+
export type RunLabOptions = RunStudyOptions;
|
|
30
|
+
/** @deprecated Use `BrowserScoringContext`, the same type. 0.109 removes `BrowserLabScoringContext`. */
|
|
31
|
+
export type BrowserLabScoringContext = BrowserScoringContext;
|
|
32
|
+
/**
|
|
33
|
+
* @deprecated Use `ComputerUseAdmissionLimitError`, the same class, so `instanceof` matches either
|
|
34
|
+
* name. 0.109 removes `CuaAdmissionLimitError`.
|
|
35
|
+
*/
|
|
36
|
+
export declare const CuaAdmissionLimitError: typeof AdmissionLimitError;
|
|
37
|
+
/** @deprecated Use `ComputerUseAdmissionLimitError`. 0.109 removes `CuaAdmissionLimitError`. */
|
|
38
|
+
export type CuaAdmissionLimitError = AdmissionLimitError;
|
|
39
|
+
/** @deprecated Use `ComputerUseAction`, the same type. 0.109 removes `CuaAction`. */
|
|
40
|
+
export type CuaAction = Action;
|
|
41
|
+
/** @deprecated Use `ComputerUseExecutor`, the same type. 0.109 removes `CuaExecutor`. */
|
|
42
|
+
export type CuaExecutor = Executor;
|
|
43
|
+
/** @deprecated Use `ComputerUseLoopOptions`, the same type. 0.109 removes `CuaLoopOptions`. */
|
|
44
|
+
export type CuaLoopOptions = LoopOptions;
|
|
45
|
+
/** @deprecated Use `ComputerUseLoopResult`, the same type. 0.109 removes `CuaLoopResult`. */
|
|
46
|
+
export type CuaLoopResult = LoopResult;
|
|
47
|
+
/** @deprecated Use `ComputerUseObservation`, the same type. 0.109 removes `CuaObservation`. */
|
|
48
|
+
export type CuaObservation = Observation;
|
|
49
|
+
/** @deprecated Use `ComputerUseProvider`, the same type. 0.109 removes `CuaProvider`. */
|
|
50
|
+
export type CuaProvider = Provider;
|
|
51
|
+
/** @deprecated Use `ComputerUseSafetyCheck`, the same type. 0.109 removes `CuaSafetyCheck`. */
|
|
52
|
+
export type CuaSafetyCheck = SafetyCheck;
|
|
53
|
+
/** @deprecated Use `ComputerUseTurn`, the same type. 0.109 removes `CuaTurn`. */
|
|
54
|
+
export type CuaTurn = Turn;
|
|
55
|
+
/** @deprecated Use `ComputerUseTurnRequest`, the same type. 0.109 removes `CuaTurnRequest`. */
|
|
56
|
+
export type CuaTurnRequest = TurnRequest;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// The names 0.107's library exported for running a lab and driving a computer-use participant.
|
|
2
|
+
// Each is the same function, constant, class or type as the name that replaces it, so an existing
|
|
3
|
+
// import, call or `instanceof` check keeps working, and editors mark it deprecated.
|
|
4
|
+
// Removed in 0.109.0: this module and its exports in src/index.ts.
|
|
5
|
+
import { CuaAdmissionLimitError as AdmissionLimitError } from "./actors/computer-use/admission-limit.js";
|
|
6
|
+
import { parseLabConfig as parseStudy } from "./lab/config.js";
|
|
7
|
+
import { LAB_CONFIG_SCHEMA as V2_SCHEMA } from "./lab/types.js";
|
|
8
|
+
import { runPackageLab as runStudy, } from "./run-lab.js";
|
|
9
|
+
/** @deprecated Use `runStudy`, the same function. 0.109 removes `runLab`. */
|
|
10
|
+
export const runLab = runStudy;
|
|
11
|
+
/** @deprecated Use `parseStudy`, the same function. 0.109 removes `parseLabConfig`. */
|
|
12
|
+
export const parseLabConfig = parseStudy;
|
|
13
|
+
/**
|
|
14
|
+
* The `humanish.lab.v2` schema id, which 0.109 stops parsing.
|
|
15
|
+
* @deprecated Write `STUDY_SCHEMA` (`humanish.study.v3`) files. 0.109 removes `LAB_CONFIG_SCHEMA`.
|
|
16
|
+
*/
|
|
17
|
+
export const LAB_CONFIG_SCHEMA = V2_SCHEMA;
|
|
18
|
+
/**
|
|
19
|
+
* @deprecated Use `ComputerUseAdmissionLimitError`, the same class, so `instanceof` matches either
|
|
20
|
+
* name. 0.109 removes `CuaAdmissionLimitError`.
|
|
21
|
+
*/
|
|
22
|
+
export const CuaAdmissionLimitError = AdmissionLimitError;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { LoadedAnalysis } from "../analysis/types.js";
|
|
2
2
|
import { type ObserverData } from "./data.js";
|
|
3
3
|
/**
|
|
4
|
-
* Resolve
|
|
4
|
+
* Resolve (and in a repo checkout, build) the Observer artifact before any run or
|
|
5
5
|
* lab work starts. A missing artifact must cost seconds at startup, never a completed
|
|
6
6
|
* session (a live participant spends real money before the render step would have noticed).
|
|
7
7
|
* Unconditional on purpose: the artifact is the only renderer now, so the fail-before-
|