humanish 0.108.0 → 0.109.1
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 +22 -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/migrate.js +15 -4
- 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 +9 -7
- 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/evidence/redaction.d.ts +11 -0
- package/dist/evidence/redaction.js +43 -0
- package/dist/feedback/draft.js +2 -2
- package/dist/feedback/export-bundle.js +5 -4
- 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/in-process-desktop.js +1 -1
- 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 +27 -27
- 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 +8 -3
- package/dist/study/migrate.js +60 -4
- 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} +4 -4
- 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} +16 -15
- 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 +6 -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 +2 -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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// against a real app (it fills forms and clicks buttons). A dry run parses and digest-pins the
|
|
11
11
|
// scenario and writes the contract bundle without touching anything.
|
|
12
12
|
//
|
|
13
|
-
// Subject provenance: an app-url run declares that
|
|
13
|
+
// Subject provenance: an app-url run declares that humanish did not provision the
|
|
14
14
|
// subject, so its build provenance is unpinned and the evidence binds to the scenario digest. A
|
|
15
15
|
// clone run records commit, env names, state provenance and a host digest, never the raw getHost
|
|
16
16
|
// URL or a secret value.
|
|
@@ -24,7 +24,7 @@ import { buildRunSource } from "../../run/bundle.js";
|
|
|
24
24
|
import { prepareSelectedOutputDirectory } from "../../run/contained-output.js";
|
|
25
25
|
import { runScope } from "../../run/run.js";
|
|
26
26
|
import { renderScriptedReviewMarkdown } from "./bundle.js";
|
|
27
|
-
import { injectedBrowser,
|
|
27
|
+
import { injectedBrowser, planScriptedStudy } from "./plan.js";
|
|
28
28
|
import { finishScriptedRun } from "./result.js";
|
|
29
29
|
import { UnsafeScriptedSessionResultError } from "./session-result.js";
|
|
30
30
|
import { prepareScriptedRun } from "./setup.js";
|
|
@@ -36,22 +36,22 @@ import { studyResultIdentity } from "../../run/study-result.js";
|
|
|
36
36
|
* The config-taking entry point. It plans, returns a refusal with the envelope the route has always
|
|
37
37
|
* returned at that refusal's stage, and otherwise runs the plan.
|
|
38
38
|
*/
|
|
39
|
-
export async function
|
|
39
|
+
export async function runScriptedBrowserStudy(options) {
|
|
40
40
|
const { config, dryRun, ...input } = options;
|
|
41
|
-
//
|
|
42
|
-
const planned =
|
|
41
|
+
// planScriptedStudy makes every configuration refusal, in the order this route always has.
|
|
42
|
+
const planned = planScriptedStudy(config, {
|
|
43
43
|
dryRun,
|
|
44
44
|
injectedBrowser: injectedBrowser(input.deps),
|
|
45
45
|
});
|
|
46
46
|
if (planned.ok)
|
|
47
47
|
return runScriptedPlan(planned.plan, input);
|
|
48
|
-
return
|
|
48
|
+
return scriptedStudyRefusal(options, planned.refusal);
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* A refused scripted
|
|
51
|
+
* A refused scripted study's result, at the refusal's stage: a before-scope refusal has its own field
|
|
52
52
|
* order and no analysis record; the others come after the output directory checks.
|
|
53
53
|
*/
|
|
54
|
-
export async function
|
|
54
|
+
export async function scriptedStudyRefusal(options, refusal) {
|
|
55
55
|
const { config, dryRun } = options;
|
|
56
56
|
const cwd = path.resolve(options.cwd);
|
|
57
57
|
const actorType = config.actors[0]?.type ?? "";
|
|
@@ -87,7 +87,7 @@ export async function scriptedLabRefusal(options, refusal) {
|
|
|
87
87
|
return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
90
|
+
* runStudyWith's step for a scripted plan. It takes no scorer, and its local checks (keys, a browser)
|
|
91
91
|
* run inside the run, so it returns the run.
|
|
92
92
|
*/
|
|
93
93
|
export function admitScriptedPlan(plan, input) {
|
|
@@ -102,7 +102,7 @@ export function admitScriptedPlan(plan, input) {
|
|
|
102
102
|
/**
|
|
103
103
|
* Run a scripted plan. The run scope gives a direct library caller the same status-record lifetime
|
|
104
104
|
* the CLI gets: returning from this function finalizes any record the run opened, whichever of its
|
|
105
|
-
* fail-closed exits it took. Each route opens its own scope; `
|
|
105
|
+
* fail-closed exits it took. Each route opens its own scope; `runStudyWith` opens none. Without this a
|
|
106
106
|
* test or an adopter calling the route directly leaves
|
|
107
107
|
* the 5s cadence ticking into a directory something else is deleting, which surfaces as an
|
|
108
108
|
* unrelated ENOTEMPTY.
|
|
@@ -125,7 +125,7 @@ async function runScriptedPlanInScope(plan, input, scope) {
|
|
|
125
125
|
runId: input.runId,
|
|
126
126
|
mintRunId: makeScriptedRunId,
|
|
127
127
|
mode: dryRun ? "dry-run" : "live",
|
|
128
|
-
|
|
128
|
+
study: plan.study,
|
|
129
129
|
renderReview: renderScriptedReviewMarkdown,
|
|
130
130
|
observer: { open: input.open === true, render: setup.deps.renderObserver },
|
|
131
131
|
});
|
|
@@ -11,7 +11,7 @@ interface ResolvedScriptedScenario {
|
|
|
11
11
|
* Resolve and consume `scenario.ref`. Path-style refs (contain a separator or end .yaml/.yml)
|
|
12
12
|
* resolve against cwd and are clamped inside it: a ../../ escape is rejected, never recorded
|
|
13
13
|
* as repo-relative provenance. Id-style refs must be public-safe tokens and resolve to
|
|
14
|
-
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed.
|
|
14
|
+
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed. planScriptedStudy
|
|
15
15
|
* has already refused a missing or blank ref.
|
|
16
16
|
*/
|
|
17
17
|
export declare function resolveScriptedScenario(projectRoot: PreparedSelectedOutputDirectory, ref: string): Promise<ResolvedScriptedScenario | {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Resolve a scripted-browser
|
|
1
|
+
// Resolve a scripted-browser study's `scenario.ref` to a committed scenario file and parse its
|
|
2
2
|
// `browser.steps` into the journey the actor runs. The ref is an id or a repo-relative path that must
|
|
3
3
|
// stay inside the project; provenance records it repo-relative with the scenario's digest.
|
|
4
4
|
import { parse as parseYaml } from "yaml";
|
|
@@ -6,14 +6,14 @@ import path from "node:path";
|
|
|
6
6
|
import { parseBrowserPersonaJourneyFromScenario } from "../../actors/scripted-browser/journey.js";
|
|
7
7
|
import { digestText } from "../../evidence/redaction.js";
|
|
8
8
|
import { readContainedRegularFile, } from "../../run/contained-output.js";
|
|
9
|
-
// Same public-safe token shape the
|
|
9
|
+
// Same public-safe token shape the study id uses; an id-style scenario.ref must match it before
|
|
10
10
|
// it is interpolated into a repo path.
|
|
11
11
|
const SCENARIO_REF_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
|
|
12
12
|
/**
|
|
13
13
|
* Resolve and consume `scenario.ref`. Path-style refs (contain a separator or end .yaml/.yml)
|
|
14
14
|
* resolve against cwd and are clamped inside it: a ../../ escape is rejected, never recorded
|
|
15
15
|
* as repo-relative provenance. Id-style refs must be public-safe tokens and resolve to
|
|
16
|
-
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed.
|
|
16
|
+
* humanish/scenarios/<ref>.yaml (then .yml). Every failure mode is fail-closed. planScriptedStudy
|
|
17
17
|
* has already refused a missing or blank ref.
|
|
18
18
|
*/
|
|
19
19
|
export async function resolveScriptedScenario(projectRoot, ref) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { ActorPersonaRef } from "../../actors/contract.js";
|
|
2
2
|
import type { BrowserPersonaJourney, ScriptedBrowserEvidenceUrlPolicy } from "../../actors/scripted-browser/types.js";
|
|
3
|
-
import type { ScriptedPlan } from "../../
|
|
4
|
-
import { type
|
|
5
|
-
import type {
|
|
3
|
+
import type { ScriptedPlan } from "../../study/plan-types.js";
|
|
4
|
+
import { type ScriptedBrowserStudyResult, type ScriptedRunInput } from "./types.js";
|
|
5
|
+
import type { StudyDeps } from "../../study/study-deps.js";
|
|
6
6
|
/** What setup hands the run: the plan's subject and scenario, keys and the browser to launch. */
|
|
7
7
|
export interface ScriptedRunSetup {
|
|
8
8
|
cwd: string;
|
|
9
9
|
physicalCwd: string;
|
|
10
|
-
deps:
|
|
10
|
+
deps: StudyDeps;
|
|
11
11
|
warnings: string[];
|
|
12
|
-
failed: (code: NonNullable<
|
|
12
|
+
failed: (code: NonNullable<ScriptedBrowserStudyResult["error"]>["code"], message: string) => ScriptedBrowserStudyResult;
|
|
13
13
|
clone: Extract<ScriptedPlan["subject"], {
|
|
14
14
|
readonly kind: "clone";
|
|
15
15
|
}> | undefined;
|
|
@@ -39,7 +39,7 @@ export interface ScriptedRunSetup {
|
|
|
39
39
|
*/
|
|
40
40
|
export declare function prepareScriptedRun(plan: ScriptedPlan, input: ScriptedRunInput): Promise<{
|
|
41
41
|
ok: false;
|
|
42
|
-
result:
|
|
42
|
+
result: ScriptedBrowserStudyResult;
|
|
43
43
|
} | {
|
|
44
44
|
ok: true;
|
|
45
45
|
setup: ScriptedRunSetup;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// the E2B key and subject env of a live clone, a browser to launch) and the values the run reads
|
|
3
3
|
// (the evidence URL policy, the scrubber for clone values, the persona and the session budget).
|
|
4
4
|
import { realpath } from "node:fs/promises";
|
|
5
|
-
import { missingKeys, missingSubjectEnv } from "../../
|
|
5
|
+
import { missingKeys, missingSubjectEnv } from "../../study/requirements.js";
|
|
6
6
|
import path from "node:path";
|
|
7
7
|
import { resolveBrowserCommand } from "../../actors/scripted-browser/browser-command.js";
|
|
8
8
|
import { describeMissingKeys } from "../../keys/key-resolution.js";
|
|
@@ -28,7 +28,7 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
28
28
|
const clone = plan.subject.kind === "clone" ? plan.subject : undefined;
|
|
29
29
|
const evidenceAppUrl = evidenceAppUrlOf(plan.subject);
|
|
30
30
|
const failed = (code, message) => ({
|
|
31
|
-
...studyResultIdentity("scripted", plan.
|
|
31
|
+
...studyResultIdentity("scripted", plan.studyId),
|
|
32
32
|
ok: false,
|
|
33
33
|
cwd,
|
|
34
34
|
actor: plan.actor,
|
|
@@ -67,14 +67,14 @@ export async function prepareScriptedRun(plan, input) {
|
|
|
67
67
|
if (missing.length > 0) {
|
|
68
68
|
return {
|
|
69
69
|
ok: false,
|
|
70
|
-
result: failed("HUMANISH_SCRIPTED_KEYS_MISSING", `Live clone scripted-browser
|
|
70
|
+
result: failed("HUMANISH_SCRIPTED_KEYS_MISSING", `Live clone scripted-browser studies require ${missing.join(" and ")} (dry-run remains $0 and does not provision a subject). ${describeMissingKeys(missing, env)}`),
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
const unsetSubjectEnv = missingSubjectEnv(plan.requirements, env);
|
|
74
74
|
if (unsetSubjectEnv.length > 0) {
|
|
75
75
|
return {
|
|
76
76
|
ok: false,
|
|
77
|
-
result: failed("HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING", `Subject env values missing for live clone scripted-browser
|
|
77
|
+
result: failed("HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING", `Subject env values missing for a live clone scripted-browser study: ${unsetSubjectEnv.join(", ")}.`),
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
const surfaces = plan.surfaces;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ScriptedPlan } from "../../
|
|
1
|
+
import type { ScriptedPlan } from "../../study/plan-types.js";
|
|
2
2
|
import { type PreparedRunArtifactPaths } from "../../run/paths.js";
|
|
3
3
|
import type { RunSubjectStateStepRecord } from "../../run/bundle.js";
|
|
4
4
|
import { type DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
5
|
+
import type { StudyDeps } from "../../study/study-deps.js";
|
|
6
|
+
import type { RunStudyHomes } from "../../study/run-study-homes.js";
|
|
7
7
|
type ScriptedCloneSubject = Extract<ScriptedPlan["subject"], {
|
|
8
8
|
readonly kind: "clone";
|
|
9
9
|
}>;
|
|
@@ -11,9 +11,9 @@ type ScriptedCloneSubject = Extract<ScriptedPlan["subject"], {
|
|
|
11
11
|
export interface ScriptedSubjectInputs {
|
|
12
12
|
plan: ScriptedPlan;
|
|
13
13
|
clone: ScriptedCloneSubject;
|
|
14
|
-
deps:
|
|
14
|
+
deps: StudyDeps;
|
|
15
15
|
/** Runs after the subject sandbox exists and before provisioning. */
|
|
16
|
-
prepareDesktop?: NonNullable<
|
|
16
|
+
prepareDesktop?: NonNullable<RunStudyHomes["prepareDesktop"]>;
|
|
17
17
|
env: Readonly<Record<string, string | undefined>>;
|
|
18
18
|
e2bApiKey: string;
|
|
19
19
|
runPaths: PreparedRunArtifactPaths;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The provisioned subject of a live clone scripted-browser
|
|
1
|
+
// The provisioned subject of a live clone scripted-browser study: one E2B desktop that clones,
|
|
2
2
|
// seeds and serves the app, exposed through a tokenless getHost URL and killed by exact id at
|
|
3
3
|
// teardown.
|
|
4
4
|
import { commandDigestOf } from "../../subject/state.js";
|
|
@@ -74,7 +74,7 @@ export class ScriptedSubject {
|
|
|
74
74
|
metadata: {
|
|
75
75
|
mode: "scripted-browser-lab",
|
|
76
76
|
tool: "humanish",
|
|
77
|
-
labId: plan.
|
|
77
|
+
labId: plan.studyId,
|
|
78
78
|
kind: "subject",
|
|
79
79
|
actor: plan.actor,
|
|
80
80
|
},
|
|
@@ -115,7 +115,7 @@ export class ScriptedSubject {
|
|
|
115
115
|
...timers,
|
|
116
116
|
});
|
|
117
117
|
if (typeof subjectDesktop.getHost !== "function") {
|
|
118
|
-
throw new Error("the installed @e2b/desktop SDK does not expose getHost(port); clone scripted-browser
|
|
118
|
+
throw new Error("the installed @e2b/desktop SDK does not expose getHost(port); clone scripted-browser studies require it to reach the provisioned subject");
|
|
119
119
|
}
|
|
120
120
|
const rawHost = subjectDesktop.getHost(servePort(clone.serve.url));
|
|
121
121
|
const hostUrl = /^https?:\/\//i.test(rawHost) ? rawHost : `https://${rawHost}`;
|
|
@@ -30,14 +30,14 @@ export function scriptedSurfaceRecords(context, surface, index, result, screensh
|
|
|
30
30
|
summary: result
|
|
31
31
|
? `Scripted-browser actor (${context.actorId}) replayed ${context.journey.scenarioId} on the ${surface.id} surface; ${result.completionReason}.`
|
|
32
32
|
: context.sessionError !== undefined
|
|
33
|
-
? `
|
|
33
|
+
? `The scripted run failed before a terminal session verdict: ${context.sessionError}`
|
|
34
34
|
: `Scripted-browser actor (${context.actorId}) against ${context.appUrl}; no session ran.`,
|
|
35
35
|
startedAt: context.createdAt,
|
|
36
36
|
updatedAt: result?.capture.capturedAt ?? context.createdAt,
|
|
37
37
|
});
|
|
38
38
|
const stream = participantStream(ids, {
|
|
39
39
|
kind: "browser",
|
|
40
|
-
label: `${surface.label} · ${context.
|
|
40
|
+
label: `${surface.label} · ${context.studyId}`,
|
|
41
41
|
status,
|
|
42
42
|
transport: "snapshot",
|
|
43
43
|
updatedAt: result?.capture.capturedAt ?? context.createdAt,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type ScriptedBrowserSessionOptions, type ScriptedBrowserSessionResult } from "../../actors/scripted-browser/actor.js";
|
|
2
|
-
import type { ScriptedPlan } from "../../
|
|
2
|
+
import type { ScriptedPlan } from "../../study/plan-types.js";
|
|
3
3
|
import { type PreparedRunArtifactPaths } from "../../run/paths.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { StudyDeps } from "../../study/study-deps.js";
|
|
5
5
|
/** One session per surface, in parallel. */
|
|
6
6
|
export declare function runScriptedSessions(session: Required<Pick<ScriptedBrowserSessionOptions, "appUrl" | "evidenceAppUrl" | "urlPolicy" | "journey" | "persona" | "timeoutMs" | "artifactRoot">>, run: {
|
|
7
7
|
surfaces: ScriptedPlan["surfaces"];
|
|
8
|
-
deps:
|
|
8
|
+
deps: StudyDeps;
|
|
9
9
|
browserCommand: string | undefined;
|
|
10
10
|
runPaths: PreparedRunArtifactPaths;
|
|
11
11
|
}): Promise<ScriptedBrowserSessionResult[]>;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import type { ActorCompletionReason, ActorStatus } from "../../actors/contract.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { StudyEvent } from "../../study/run-study-events.js";
|
|
3
3
|
import type { AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { StudyConfig } from "../../study/types.js";
|
|
5
5
|
import type { ObserverResult } from "../../observer/render.js";
|
|
6
6
|
import type { RunSubjectProvenance } from "../../run/bundle.js";
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
7
|
+
import type { StudyDeps } from "../../study/study-deps.js";
|
|
8
|
+
import type { RunStudyHomes } from "../../study/run-study-homes.js";
|
|
9
9
|
import { type StudyResultIdentity } from "../../run/study-result.js";
|
|
10
|
-
/** What a scripted run takes besides its plan. The plan carries the config, dry run and
|
|
11
|
-
export type ScriptedRunInput = Omit<
|
|
12
|
-
export interface
|
|
10
|
+
/** What a scripted run takes besides its plan. The plan carries the config, dry run and study. */
|
|
11
|
+
export type ScriptedRunInput = Omit<RunScriptedBrowserStudyOptions, "config" | "dryRun">;
|
|
12
|
+
export interface RunScriptedBrowserStudyOptions {
|
|
13
13
|
/** Cancels post-run analysis only. */
|
|
14
14
|
analysisSignal?: AbortSignal;
|
|
15
|
-
/** Reports the analysis window to onEvent; built by
|
|
16
|
-
emit?: (event:
|
|
15
|
+
/** Reports the analysis window to onEvent; built by normalizeRunStudyOptions. */
|
|
16
|
+
emit?: (event: StudyEvent) => void;
|
|
17
17
|
cwd: string;
|
|
18
|
-
config:
|
|
18
|
+
config: StudyConfig;
|
|
19
19
|
/** Resolved upstream (scenario.mode + CLI override); defaults safe (dry-run). */
|
|
20
20
|
dryRun: boolean;
|
|
21
21
|
open?: boolean;
|
|
@@ -23,20 +23,20 @@ export interface RunScriptedBrowserLabOptions {
|
|
|
23
23
|
/** Keys and subject env for the run. Defaults to process.env. Values are scrubbed; names persist. */
|
|
24
24
|
env?: Readonly<Record<string, string | undefined>>;
|
|
25
25
|
/** Runs after a clone subject's sandbox exists and before provisioning. */
|
|
26
|
-
prepareDesktop?: NonNullable<
|
|
26
|
+
prepareDesktop?: NonNullable<RunStudyHomes["prepareDesktop"]>;
|
|
27
27
|
/** Test seams: the browser, the session, the E2B module, timers, the renderer and the clock. */
|
|
28
|
-
deps?:
|
|
28
|
+
deps?: StudyDeps;
|
|
29
29
|
}
|
|
30
|
-
interface
|
|
30
|
+
interface ScriptedBrowserStudySession {
|
|
31
31
|
surface: string;
|
|
32
32
|
status: ActorStatus;
|
|
33
33
|
completionReason: ActorCompletionReason;
|
|
34
34
|
reason: string;
|
|
35
35
|
screenshots: number;
|
|
36
36
|
}
|
|
37
|
-
export interface
|
|
37
|
+
export interface ScriptedBrowserStudyResult extends AutomaticAnalysisResult, StudyResultIdentity<"scripted"> {
|
|
38
38
|
/** True when the bundle verified and (dry-run, or every session reached a terminal verdict
|
|
39
|
-
* without a harness error). The subject failing the script is successful evidence, and the
|
|
39
|
+
* without a harness error). The subject failing the script is successful evidence, and the run
|
|
40
40
|
* does not fail for it. */
|
|
41
41
|
ok: boolean;
|
|
42
42
|
cwd: string;
|
|
@@ -58,11 +58,11 @@ export interface ScriptedBrowserLabResult extends AutomaticAnalysisResult, Study
|
|
|
58
58
|
sourceDigest: string;
|
|
59
59
|
steps: number;
|
|
60
60
|
};
|
|
61
|
-
sessions:
|
|
61
|
+
sessions: ScriptedBrowserStudySession[];
|
|
62
62
|
observer?: ObserverResult;
|
|
63
63
|
warnings: string[];
|
|
64
64
|
error?: {
|
|
65
|
-
code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_SCRIPTED_FAILED" | "HUMANISH_SCRIPTED_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_SUBJECT_UNSAFE" | "HUMANISH_SCRIPTED_BROWSER_MISSING" | "HUMANISH_SCRIPTED_KEYS_MISSING" | "HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING" | "HUMANISH_SCRIPTED_GETHOST_UNAVAILABLE" | "HUMANISH_RUN_ID_IN_USE";
|
|
65
|
+
code: "HUMANISH_STUDY_ANALYSIS_INVALID" | "HUMANISH_STUDY_TASKS_UNSUPPORTED" | "HUMANISH_STUDY_OPTION_UNSUPPORTED" | "HUMANISH_STUDY_V2_UNSUPPORTED" | "HUMANISH_SCRIPTED_FAILED" | "HUMANISH_SCRIPTED_ACTOR_UNSUPPORTED" | "HUMANISH_SCRIPTED_SCENARIO_INVALID" | "HUMANISH_SCRIPTED_SUBJECT_UNSAFE" | "HUMANISH_SCRIPTED_BROWSER_MISSING" | "HUMANISH_SCRIPTED_KEYS_MISSING" | "HUMANISH_SCRIPTED_SUBJECT_ENV_MISSING" | "HUMANISH_SCRIPTED_GETHOST_UNAVAILABLE" | "HUMANISH_RUN_ID_IN_USE";
|
|
66
66
|
message: string;
|
|
67
67
|
};
|
|
68
68
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// The scripted-browser
|
|
1
|
+
// The scripted-browser study's schema constant, options and result types.
|
|
2
2
|
import {} from "../../run/study-result.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Each participant's records in a concurrent shared-world bundle: its simulation, its stream and
|
|
2
2
|
// its events, projected from the actor's run result (or from the declaration on a dry run or while
|
|
3
3
|
// running).
|
|
4
|
-
import { participantAssignment } from "../../
|
|
4
|
+
import { participantAssignment } from "../../study/participant-assignment.js";
|
|
5
5
|
import { participantEvent, participantRecord, participantStream, } from "../../run/participant-records.js";
|
|
6
6
|
import { declaredScreenForRender } from "../../substrates/e2b/desktop-geometry.js";
|
|
7
7
|
import { publicSafeRouteLabel } from "./provenance.js";
|
|
@@ -68,7 +68,7 @@ function sharedWorldSimulation(ctx, spec, index, view) {
|
|
|
68
68
|
const { taxonomy, outcome, session } = view;
|
|
69
69
|
return participantRecord(spec, index + 1, {
|
|
70
70
|
personaId: spec.persona.id,
|
|
71
|
-
scenarioId: `concurrent-shared-world-${args.plan.
|
|
71
|
+
scenarioId: `concurrent-shared-world-${args.plan.studyId}`,
|
|
72
72
|
status: view.status,
|
|
73
73
|
streamKind: "browser",
|
|
74
74
|
mode: "browser-sim",
|
|
@@ -93,7 +93,7 @@ function sharedWorldStream(ctx, spec, index, view) {
|
|
|
93
93
|
? {}
|
|
94
94
|
: { assignment: participantAssignment(spec.evidenceAssignment) }),
|
|
95
95
|
kind: "browser",
|
|
96
|
-
label: `Concurrent persona ${spec.planned.id}${taxonomy} · ${args.plan.
|
|
96
|
+
label: `Concurrent persona ${spec.planned.id}${taxonomy} · ${args.plan.studyId}`,
|
|
97
97
|
status: view.status,
|
|
98
98
|
transport: "snapshot",
|
|
99
99
|
updatedAt: args.run.createdAt,
|
|
@@ -14,6 +14,7 @@ import { hostOriginDigest } from "./provenance.js";
|
|
|
14
14
|
import { participantEvent, participantIds } from "../../run/participant-records.js";
|
|
15
15
|
import { sharedWorldParticipantRecords } from "./bundle-records.js";
|
|
16
16
|
import { CONCURRENT_ATTRIBUTION_LIMITS, EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS, } from "./types.js";
|
|
17
|
+
import { plural } from "../../run/text.js";
|
|
17
18
|
/** Max windows live at the same instant (sweep over start/end points). The simultaneity
|
|
18
19
|
* count: the participant count says how many existed; this says how many ever ran at once. */
|
|
19
20
|
export function maxSimultaneousWindows(windows) {
|
|
@@ -86,7 +87,7 @@ function formatSharedWorldActorOutcomes(outcomes, expectedCount) {
|
|
|
86
87
|
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
87
88
|
.map(([reason, count]) => `${reason} ${count}/${expectedCount}`)
|
|
88
89
|
.join(", ");
|
|
89
|
-
return `${passedSessions}/${expectedCount
|
|
90
|
+
return `${passedSessions}/${plural(expectedCount, "actor session")} passed credibility checks; mission endpoint: ${goalSatisfiedSessions}/${expectedCount} ended goal_satisfied; completion reasons: ${completionReasons}`;
|
|
90
91
|
}
|
|
91
92
|
/** The run's first two events: its creation and the shared plane's provenance. */
|
|
92
93
|
function planeEvents(args, external) {
|
|
@@ -97,7 +98,7 @@ function planeEvents(args, external) {
|
|
|
97
98
|
at: createdAt,
|
|
98
99
|
level: "info",
|
|
99
100
|
type: "concurrent-shared-world.run.created",
|
|
100
|
-
message: `Created a concurrent shared-world run for ${plan.
|
|
101
|
+
message: `Created a concurrent shared-world run for ${plan.studyId} (actor ${descriptor.id}, ${plural(actorSpecs.length, "persona")} on one shared app, at most ${plan.concurrency} at once).`,
|
|
101
102
|
});
|
|
102
103
|
// Human-readable plane label, byte-stable for the clone route. local-tree has no repo slug: it
|
|
103
104
|
// labels the packed archive instead (archiveSha256 + dirty/clean when the packed root was a git
|
|
@@ -111,7 +112,7 @@ function planeEvents(args, external) {
|
|
|
111
112
|
// External-public plane provenance differs: an operator-declared, operator-owned public
|
|
112
113
|
// deployment humanish neither provisioned nor seeded, with no getHost, no clone and no synthetic
|
|
113
114
|
// attestation (claiming synthetic on a real site is a lie). The origin persists digest-only.
|
|
114
|
-
//
|
|
115
|
+
// planSharedWorldStudy refuses an external-public plane without a declared owner; the fallback
|
|
115
116
|
// says so rather than naming one.
|
|
116
117
|
const externalPlaneOwner = plan.plane.kind === "external-public" ? plan.plane.owner : "(undeclared)";
|
|
117
118
|
events.push(participantEvent(actorSpecs[0] ?? participantIds(0), {
|
|
@@ -120,7 +121,7 @@ function planeEvents(args, external) {
|
|
|
120
121
|
level: "info",
|
|
121
122
|
type: "concurrent-shared-world.plane.provenance",
|
|
122
123
|
message: external
|
|
123
|
-
? `Shared app: a public deployment the operator declares they own (${externalPlaneOwner}, authorized), used as it is, with no sandbox, clone or seed. humanish observed that each participant reached the declared origin (publicOriginDigest); it did not create or control the app. Ownership is the
|
|
124
|
+
? `Shared app: a public deployment the operator declares they own (${externalPlaneOwner}, authorized), used as it is, with no sandbox, clone or seed. humanish observed that each participant reached the declared origin (publicOriginDigest); it did not create or control the app. Ownership is the study's declaration, and the data is not claimed to be synthetic.`
|
|
124
125
|
: dryRun
|
|
125
126
|
? `Shared app declared: ${dryRunPlaneLabel}, to be served in the sandbox at a public sandbox URL (dry run: nothing ${args.subject.source === "local-tree" ? "packed" : "cloned"}). Seed recipe ${args.seedDigest}; synthetic subject, as the study declares; env names: ${args.subject.envNames?.join(", ") || "none"} (values never stored).`
|
|
126
127
|
: `Shared app: ${livePlaneLabel}, served at a public sandbox URL humanish created; seed recipe ${args.seedDigest}; synthetic subject, as the study declares; env names: ${args.subject.envNames?.join(", ") || "none"} (values never stored).`,
|
|
@@ -249,7 +250,7 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
|
|
|
249
250
|
const deltas = (stateSeries ?? []).filter((snapshot, i) => i > 0 && snapshot.digest !== (stateSeries ?? [])[i - 1].digest).length;
|
|
250
251
|
const stateSeriesLabel = external
|
|
251
252
|
? "stateSeries omitted (no authoritative shared-state proof on the external-public plane)"
|
|
252
|
-
: `stateSeries ${(stateSeries ?? []).length
|
|
253
|
+
: `stateSeries ${plural((stateSeries ?? []).length, "snapshot")}, ${plural(deltas, "delta")}`;
|
|
253
254
|
const convergenceLabel = external
|
|
254
255
|
? `; lobby convergence ${args.lobbyConvergenceDigest ? "shown (all participants reached one /lobby/CODE)" : "not observed"}`
|
|
255
256
|
: "";
|
|
@@ -262,7 +263,7 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
|
|
|
262
263
|
at: createdAt,
|
|
263
264
|
level: "info",
|
|
264
265
|
type: "concurrent-shared-world.concurrency",
|
|
265
|
-
message: `Concurrency: ${windows.length
|
|
266
|
+
message: `Concurrency: ${plural(windows.length, "participant")}${dryRun ? " (dry run; $0)" : `, up to ${maxLive} live at once (cap ${capForReport}), overlap ${overlaps ? "shown" : "not observed"}`}; ${stateSeriesLabel}${convergenceLabel}. Attribution ceiling: ${sharedWorld.attributionLimits.join(", ")}. ${dryRun ? "This dry run proves nothing about live concurrency, scale, or adoption." : "This run reports only its own observed overlap and state changes; it does not prove scale, repeatability, or adopter-harness replacement."}`,
|
|
266
267
|
});
|
|
267
268
|
// The judge's verdict (judgeSharedWorld): every participant produced a terminal, engaged, passed
|
|
268
269
|
// session. Mission endpoint and completion reasons are reported separately below; `outcomes[].ok`
|
|
@@ -277,13 +278,13 @@ function concurrencyReview(args, external, inProgress, evidence, events, nextEve
|
|
|
277
278
|
// report "state delta(s) under load" (live). It reports lobby convergence instead.
|
|
278
279
|
summary: dryRun
|
|
279
280
|
? external
|
|
280
|
-
? `Concurrent shared-world dry run: ${actorSpecs.length
|
|
281
|
-
: `Concurrent shared-world dry run: ${actorSpecs.length
|
|
281
|
+
? `Concurrent shared-world dry run: ${plural(actorSpecs.length, "persona")} declared against one public deployment, used as it is (no sandbox, clone or seed); no sandboxes launched, $0 spent.`
|
|
282
|
+
: `Concurrent shared-world dry run: ${plural(actorSpecs.length, "persona")} declared against one app served at a public sandbox URL (${descriptor.id}); no sandboxes launched, $0 spent.`
|
|
282
283
|
: inProgress
|
|
283
|
-
? `In-progress concurrent shared-world Observer snapshot: ${actorSpecs.length
|
|
284
|
+
? `In-progress concurrent shared-world Observer snapshot: ${plural(actorSpecs.length, "persona")} running against one shared app; final verification is pending.`
|
|
284
285
|
: external
|
|
285
286
|
? `Concurrent shared-world (one public deployment, ${actorSpecs.length} personas at once): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${args.lobbyConvergenceDigest ? `${actorSpecs.length} participants converged on one lobby` : "lobby convergence not observed"}.`
|
|
286
|
-
: `Concurrent shared-world (one shared app, ${actorSpecs.length} personas at once): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${deltas
|
|
287
|
+
: `Concurrent shared-world (one shared app, ${actorSpecs.length} personas at once): swarm ${verdict === "pass" ? "ran coherently" : "did not run coherently"}; ${actorOutcomeSummary}; overlap ${overlaps ? "proven" : "not observed"}; ${plural(deltas, "state delta")} under load.`,
|
|
287
288
|
gaps: dryRun
|
|
288
289
|
? [
|
|
289
290
|
"This dry run launched no concurrent shared-world session; it checks the evidence shape only, not live behavior, scale, or adopter-harness replacement.",
|
|
@@ -333,16 +334,16 @@ export function buildConcurrentSharedWorldBundle(args) {
|
|
|
333
334
|
persona: {
|
|
334
335
|
id: actorSpecs[0]?.persona.id ?? "concurrent-persona",
|
|
335
336
|
name: `Concurrent shared-world swarm (${actorSpecs.length} personas)`,
|
|
336
|
-
source: `study:${plan.
|
|
337
|
+
source: `study:${plan.studyId}`,
|
|
337
338
|
sourceDigest: actorSpecs[0]?.persona.promptDigest ?? args.seedDigest,
|
|
338
339
|
},
|
|
339
340
|
scenario: {
|
|
340
|
-
id: `concurrent-shared-world-${plan.
|
|
341
|
-
title: plan.title ?? `Concurrent shared-world: ${plan.
|
|
341
|
+
id: `concurrent-shared-world-${plan.studyId}`,
|
|
342
|
+
title: plan.title ?? `Concurrent shared-world: ${plan.studyId}`,
|
|
342
343
|
goal: redactText(actorSpecs[0]?.evidenceInstructions ??
|
|
343
344
|
actorSpecs[0]?.instructions ??
|
|
344
345
|
"Concurrent shared-world interaction."),
|
|
345
|
-
source: `study:${plan.
|
|
346
|
+
source: `study:${plan.studyId}`,
|
|
346
347
|
sourceDigest: actorSpecs[0]?.persona.promptDigest ?? args.seedDigest,
|
|
347
348
|
},
|
|
348
349
|
lifecycle: [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Shell } from "../../substrates/shell.js";
|
|
2
2
|
import { type DetachedTimers } from "../../substrates/detached.js";
|
|
3
|
-
import { type
|
|
3
|
+
import { type StudySubjectState, type StudySubjectStateCheckpoint } from "../../study/types.js";
|
|
4
4
|
import { type SharedWorldCheckpoint } from "../../run/shared-world-evidence.js";
|
|
5
5
|
/** Combine a snapshot's per-probe digests into one sha256-16 (digest-only; no raw value). */
|
|
6
6
|
export declare function combineCheckpointDigest(parts: string[]): string;
|
|
@@ -15,11 +15,11 @@ export declare function runCheckpointSnapshot(args: {
|
|
|
15
15
|
shell: Shell;
|
|
16
16
|
snapshotIndex: number;
|
|
17
17
|
name: string;
|
|
18
|
-
checkpoints:
|
|
18
|
+
checkpoints: StudySubjectStateCheckpoint[];
|
|
19
19
|
prevDigest: string | undefined;
|
|
20
20
|
scrub: (text: string) => string;
|
|
21
21
|
requestTimeoutMs: number;
|
|
22
22
|
timers: DetachedTimers;
|
|
23
23
|
}): Promise<SharedWorldCheckpoint>;
|
|
24
24
|
/** sha256-16 over the ordered seed-step command digests: the seeded-state recipe identity. */
|
|
25
|
-
export declare function seedRecipeDigest(state:
|
|
25
|
+
export declare function seedRecipeDigest(state: StudySubjectState | undefined): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { commandDigestOf } from "../../subject/state.js";
|
|
2
2
|
import { SUBJECT_DIR } from "../../subject/steps.js";
|
|
3
3
|
import { runDetachedStep } from "../../substrates/detached.js";
|
|
4
|
-
import {} from "../../
|
|
4
|
+
import {} from "../../study/types.js";
|
|
5
5
|
import { redactText } from "../../evidence/redaction.js";
|
|
6
6
|
import {} from "../../run/shared-world-evidence.js";
|
|
7
7
|
// Per-checkpoint probe budget (read-only aggregate probes are fast).
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { type ReceivingSource } from "../../comms/receiving-runtime.js";
|
|
2
|
-
import type { SharedWorldPlan } from "../../
|
|
2
|
+
import type { SharedWorldPlan } from "../../study/plan-types.js";
|
|
3
3
|
import type { CommsReceivingRun } from "../../comms/receiving.js";
|
|
4
4
|
import { type DeployedCommsCatch } from "../../comms/sandbox-catch.js";
|
|
5
|
-
import type {
|
|
5
|
+
import type { StudyCommsEmail, StudyConfig } from "../../study/types.js";
|
|
6
6
|
import type { Shell } from "../../substrates/shell.js";
|
|
7
7
|
import type { ConcurrentSharedWorldPlaneClass, ExternalCommsWiring, PlaneContext } from "./types.js";
|
|
8
|
-
/** The in-sandbox email catch a provisioned plane deploys, when the
|
|
8
|
+
/** The in-sandbox email catch a provisioned plane deploys, when the study declares one. */
|
|
9
9
|
export interface SubjectComms {
|
|
10
|
-
email:
|
|
10
|
+
email: StudyCommsEmail | undefined;
|
|
11
11
|
port: number | undefined;
|
|
12
12
|
/** The catch's base URL, injected into the subject sandbox's env at create. */
|
|
13
13
|
env: Record<string, string>;
|
|
14
14
|
}
|
|
15
|
-
export declare function subjectCommsOf(config: Pick<
|
|
15
|
+
export declare function subjectCommsOf(config: Pick<StudyConfig, "comms">, planeClass: ConcurrentSharedWorldPlaneClass): SubjectComms;
|
|
16
16
|
/**
|
|
17
17
|
* Adopter-hosted ingress: on the external-public plane the harness provisions nothing, so
|
|
18
18
|
* it cannot host a catch. The operator can, and then humanish still does every other part of
|
|
@@ -21,7 +21,7 @@ export declare function subjectCommsOf(config: Pick<LabConfig, "comms">, planeCl
|
|
|
21
21
|
* the previously-inert block into a working one. Returns an error message when the declared catch
|
|
22
22
|
* does not answer as a humanish catch.
|
|
23
23
|
*/
|
|
24
|
-
export declare function prepareExternalComms(config: Pick<
|
|
24
|
+
export declare function prepareExternalComms(config: Pick<StudyConfig, "comms">, planeClass: ConcurrentSharedWorldPlaneClass, dryRun: boolean, warnings: string[], env: Record<string, string | undefined>): Promise<{
|
|
25
25
|
ok: true;
|
|
26
26
|
wiring: ExternalCommsWiring | undefined;
|
|
27
27
|
} | {
|
|
@@ -36,7 +36,7 @@ export declare function prepareExternalComms(config: Pick<LabConfig, "comms">, p
|
|
|
36
36
|
* never blocks teardown (invariant: all sandboxes torn down by id in the plane's finally). Returns
|
|
37
37
|
* the thread's path when one was written.
|
|
38
38
|
*/
|
|
39
|
-
export declare function drainSubjectComms(ctx: PlaneContext, commsEmail:
|
|
39
|
+
export declare function drainSubjectComms(ctx: PlaneContext, commsEmail: StudyCommsEmail, subjectShell: Shell, deployedComms: DeployedCommsCatch): Promise<string | undefined>;
|
|
40
40
|
/**
|
|
41
41
|
* Adopter-hosted drain: same routing and digest-only artifact as the in-sandbox
|
|
42
42
|
* catch. Only the transport differs (HTTP GET /deliveries against the catch the operator
|
|
@@ -44,10 +44,10 @@ export declare function drainSubjectComms(ctx: PlaneContext, commsEmail: LabComm
|
|
|
44
44
|
* masks the run's own outcome. Returns the thread's path when one was written.
|
|
45
45
|
*/
|
|
46
46
|
export declare function drainExternalComms(ctx: PlaneContext, comms: ExternalCommsWiring): Promise<string | undefined>;
|
|
47
|
-
/** What receiving guards: the
|
|
47
|
+
/** What receiving guards: the study's email declaration and the subject env names and values. */
|
|
48
48
|
export declare function receivingSourceOf(residual: SharedWorldPlan["residual"], env: readonly string[]): ReceivingSource;
|
|
49
49
|
/**
|
|
50
|
-
* Real email receiving, when the
|
|
50
|
+
* Real email receiving, when the study declares it on a live run. It registers the connection's
|
|
51
51
|
* secrets with the run's scrub before any desktop starts. Returns the message the run fails with
|
|
52
52
|
* when setup fails.
|
|
53
53
|
*/
|
|
@@ -7,7 +7,8 @@ import { prepareReceivingRun } from "../../comms/receiving-runtime.js";
|
|
|
7
7
|
import { DEFAULT_SANDBOX_CATCH_PORT, collectCommsThread, externalCatchHealthy, externalInboxUrl, } from "../../comms/sandbox-catch.js";
|
|
8
8
|
import { redactText, toErrorMessage } from "../../evidence/redaction.js";
|
|
9
9
|
import { writeContainedOutputFile } from "../../run/contained-output.js";
|
|
10
|
-
import { addressedRecipients } from "../../
|
|
10
|
+
import { addressedRecipients } from "../../study/parse/comms.js";
|
|
11
|
+
import { plural } from "../../run/text.js";
|
|
11
12
|
// Off-app comms: on the provisioned-getHost plane the harness owns the one subject sandbox, so
|
|
12
13
|
// it can redirect the app's email-API sends into an in-sandbox catch and evidence them. Gated entirely
|
|
13
14
|
// on config.comms: no comms declared → zero change. The base-URL env is injected into the subject
|
|
@@ -52,7 +53,7 @@ export async function prepareExternalComms(config, planeClass, dryRun, warnings,
|
|
|
52
53
|
code: "HUMANISH_SHARED_WORLD_COMMS_TOKEN_INVALID",
|
|
53
54
|
message: tokenRefusal,
|
|
54
55
|
};
|
|
55
|
-
// Fail closed before any actor sandbox is created: a comms
|
|
56
|
+
// Fail closed before any actor sandbox is created: a comms study whose catch is unreachable
|
|
56
57
|
// collects nothing while every participant still spends. The probe asserts our service marker in
|
|
57
58
|
// /health, so an adopter's proxy answering 200 for everything cannot pass for a catch.
|
|
58
59
|
if (!dryRun && !(await externalCatchHealthy(externalComms))) {
|
|
@@ -91,7 +92,7 @@ export async function drainSubjectComms(ctx, commsEmail, subjectShell, deployedC
|
|
|
91
92
|
return "comms/thread.json";
|
|
92
93
|
}
|
|
93
94
|
else if (collected.captured > 0) {
|
|
94
|
-
warnings.push(`The email catch captured ${collected.captured
|
|
95
|
+
warnings.push(`The email catch captured ${plural(collected.captured, "email send")}, but none matched a declared recipient inbox, so no email evidence was written. Set comms.email.recipients[].address to the address the app sends to.`);
|
|
95
96
|
}
|
|
96
97
|
else {
|
|
97
98
|
// Zero captures is the silent-broken shape: the app never posted to the catch.
|
|
@@ -120,7 +121,7 @@ export async function drainExternalComms(ctx, comms) {
|
|
|
120
121
|
ctx.warnings.push(...warnings);
|
|
121
122
|
return path;
|
|
122
123
|
}
|
|
123
|
-
/** What receiving guards: the
|
|
124
|
+
/** What receiving guards: the study's email declaration and the subject env names and values. */
|
|
124
125
|
export function receivingSourceOf(residual, env) {
|
|
125
126
|
const { comms } = residual;
|
|
126
127
|
const { envValues } = residual.subject;
|
|
@@ -130,7 +131,7 @@ export function receivingSourceOf(residual, env) {
|
|
|
130
131
|
};
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
133
|
-
* Real email receiving, when the
|
|
134
|
+
* Real email receiving, when the study declares it on a live run. It registers the connection's
|
|
134
135
|
* secrets with the run's scrub before any desktop starts. Returns the message the run fails with
|
|
135
136
|
* when setup fails.
|
|
136
137
|
*/
|