humanish 0.106.1 → 0.107.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +4 -4
- package/ARCHITECTURE.md +17 -16
- package/CHANGELOG.md +14 -0
- package/CONTEXT.md +42 -39
- package/CONTRIBUTING.md +8 -8
- package/README.md +8 -3
- package/dist/actors/codex/app-server-client.js +2 -1
- package/dist/actors/codex/app-server-trace.d.ts +0 -1
- package/dist/actors/codex/app-server-trace.js +1 -3
- package/dist/actors/codex/app-server.js +2 -1
- package/dist/actors/codex/protocol-compat.d.ts +27 -0
- package/dist/actors/codex/protocol-compat.js +357 -0
- package/dist/actors/codex/protocol-contract.d.ts +61 -0
- package/dist/actors/codex/protocol-contract.js +471 -0
- package/dist/actors/codex/qualified-versions.d.ts +30 -3
- package/dist/actors/codex/qualified-versions.js +50 -5
- package/dist/actors/codex/restricted-executable.d.ts +24 -0
- package/dist/actors/codex/restricted-executable.js +97 -22
- package/dist/actors/codex/restricted-launch.d.ts +7 -1
- package/dist/actors/codex/restricted-launch.js +42 -3
- package/dist/actors/codex/restricted-notifications.d.ts +101 -0
- package/dist/actors/codex/restricted-notifications.js +277 -0
- package/dist/actors/codex/restricted-participant.d.ts +30 -0
- package/dist/actors/codex/restricted-participant.js +60 -2
- package/dist/actors/codex/restricted-policy.d.ts +9 -1
- package/dist/actors/codex/restricted-session.d.ts +14 -1
- package/dist/actors/codex/restricted-session.js +50 -17
- package/dist/actors/codex/restricted-transport.d.ts +29 -0
- package/dist/actors/codex/restricted-transport.js +139 -27
- package/dist/actors/codex/restricted-turn.d.ts +19 -4
- package/dist/actors/codex/restricted-turn.js +43 -30
- package/dist/actors/computer-use/actor.d.ts +1 -1
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/loop/backstop.js +1 -1
- package/dist/actors/computer-use/loop/ending.d.ts +2 -2
- package/dist/actors/computer-use/loop/ending.js +2 -2
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +3 -3
- package/dist/actors/computer-use/loop/trace.js +2 -2
- package/dist/actors/computer-use/loop/types.d.ts +14 -5
- package/dist/actors/computer-use/loop.js +4 -4
- package/dist/actors/computer-use/openai-provider.d.ts +1 -1
- package/dist/actors/computer-use/openai-provider.js +2 -2
- package/dist/actors/contract.d.ts +9 -7
- package/dist/actors/local-agent/cli.js +1 -1
- package/dist/actors/scripted-browser/actor.d.ts +2 -2
- package/dist/actors/scripted-browser/journey.js +15 -4
- package/dist/actors/scripted-browser/steps.js +18 -0
- package/dist/actors/scripted-browser/types.d.ts +11 -1
- package/dist/actors/stop-conditions.js +1 -3
- package/dist/analysis/automatic-completion.d.ts +13 -8
- package/dist/analysis/automatic-completion.js +14 -8
- package/dist/analysis/automatic-config.d.ts +1 -1
- package/dist/analysis/automatic-config.js +2 -2
- package/dist/analysis/automatic.d.ts +10 -4
- package/dist/analysis/automatic.js +17 -13
- package/dist/analysis/diagnostics.d.ts +23 -0
- package/dist/analysis/diagnostics.js +112 -0
- package/dist/analysis/evidence-sources.js +2 -2
- package/dist/analysis/evidence.js +6 -6
- package/dist/analysis/execute.d.ts +7 -1
- package/dist/analysis/execute.js +39 -12
- package/dist/analysis/job.d.ts +8 -5
- package/dist/analysis/job.js +15 -14
- package/dist/analysis/load.d.ts +1 -1
- package/dist/analysis/load.js +5 -5
- package/dist/analysis/provider.d.ts +9 -1
- package/dist/analysis/restricted-codex.d.ts +2 -0
- package/dist/analysis/restricted-codex.js +10 -1
- package/dist/analysis/service.d.ts +2 -0
- package/dist/analysis/service.js +31 -12
- package/dist/analysis/sharing.d.ts +2 -2
- package/dist/analysis/sharing.js +5 -5
- package/dist/analysis/store-executions.d.ts +5 -5
- package/dist/analysis/store-executions.js +12 -12
- package/dist/analysis/store.d.ts +4 -4
- package/dist/analysis/store.js +13 -13
- package/dist/cli/commands/analysis-signals.d.ts +2 -1
- package/dist/cli/commands/analysis-signals.js +4 -1
- package/dist/cli/commands/analyze.js +4 -2
- package/dist/cli/commands/comms.js +8 -1
- package/dist/cli/commands/lab-route-computer-use.d.ts +0 -2
- package/dist/cli/commands/lab-route-computer-use.js +26 -14
- package/dist/cli/commands/lab-route-preview.d.ts +1 -3
- package/dist/cli/commands/lab-route-preview.js +3 -4
- package/dist/cli/commands/lab-route-run.d.ts +6 -4
- package/dist/cli/commands/lab-route-run.js +6 -2
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -2
- package/dist/cli/commands/lab-route-scripted.js +0 -1
- package/dist/cli/commands/lab-route-shared-world.d.ts +0 -2
- package/dist/cli/commands/lab-route-shared-world.js +0 -1
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -2
- package/dist/cli/commands/lab-route-terminal.js +0 -1
- package/dist/cli/commands/lab-run.js +76 -45
- package/dist/cli/commands/lab-scorer.d.ts +0 -2
- package/dist/cli/commands/lab.js +12 -6
- package/dist/cli/commands/observe.js +22 -0
- package/dist/cli/commands/run-signals.d.ts +30 -0
- package/dist/cli/commands/run-signals.js +146 -0
- package/dist/cli/commands/runs.js +10 -8
- package/dist/cli/commands/watch.js +12 -10
- package/dist/cli/doctor.d.ts +3 -0
- package/dist/cli/doctor.js +10 -2
- package/dist/cli/io.d.ts +5 -4
- package/dist/cli/io.js +12 -8
- package/dist/cli/program.js +3 -3
- package/dist/cli/renamed-options.d.ts +11 -0
- package/dist/cli/renamed-options.js +18 -0
- package/dist/cli/telemetry.d.ts +2 -2
- package/dist/cli/telemetry.js +1 -1
- package/dist/comms/capture-surface.d.ts +1 -1
- package/dist/comms/catch-host.d.ts +1 -1
- package/dist/comms/connections.js +4 -4
- package/dist/comms/external-evidence.d.ts +27 -0
- package/dist/comms/external-evidence.js +93 -0
- package/dist/comms/lease-store.js +7 -7
- package/dist/comms/types.js +1 -1
- package/dist/evidence/browser-hygiene.d.ts +1 -1
- package/dist/evidence/browser-hygiene.js +1 -1
- package/dist/evidence/redaction.js +1 -1
- package/dist/evidence/secret-scrub.d.ts +9 -0
- package/dist/evidence/secret-scrub.js +96 -0
- package/dist/feedback/draft.js +7 -9
- package/dist/feedback/export-bundle.js +4 -4
- package/dist/feedback/export.js +9 -9
- package/dist/feedback/feedback.d.ts +1 -1
- package/dist/index.d.ts +3 -6
- package/dist/index.js +3 -6
- package/dist/keys/key-resolution.d.ts +3 -1
- package/dist/keys/key-resolution.js +18 -16
- package/dist/lab/adapter-extension.d.ts +28 -6
- package/dist/lab/adapter-extension.js +65 -126
- package/dist/lab/adapter-scorer-loader.d.ts +25 -5
- package/dist/lab/adapter-scorer-loader.js +24 -0
- package/dist/lab/composition-rules.js +20 -20
- package/dist/lab/config.js +28 -26
- package/dist/lab/device-presets.d.ts +2 -2
- package/dist/lab/discover.js +1 -3
- package/dist/lab/doctor.d.ts +44 -9
- package/dist/lab/doctor.js +149 -41
- package/dist/lab/init-plan.js +1 -3
- package/dist/lab/keys.js +1 -1
- package/dist/lab/lab-deps.d.ts +85 -0
- package/dist/lab/lab-deps.js +4 -0
- package/dist/lab/parse/actors.js +8 -7
- package/dist/lab/parse/comms.js +3 -2
- package/dist/lab/parse/execution.js +3 -2
- package/dist/lab/parse/subject-state.js +2 -1
- package/dist/lab/parse/subject.js +2 -1
- package/dist/lab/parse/values.d.ts +0 -1
- package/dist/lab/parse/values.js +0 -3
- package/dist/lab/persona-resolve.d.ts +3 -3
- package/dist/lab/persona-resolve.js +4 -4
- package/dist/lab/persona.js +1 -3
- package/dist/lab/plan-base.d.ts +0 -2
- package/dist/lab/plan-base.js +6 -4
- package/dist/lab/plan-participants.d.ts +5 -5
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +22 -4
- package/dist/lab/plan.d.ts +3 -11
- package/dist/lab/plan.js +18 -42
- package/dist/lab/preflight-result.js +0 -2
- package/dist/lab/preflight.d.ts +0 -3
- package/dist/lab/preflight.js +1 -1
- package/dist/lab/requirements.d.ts +20 -0
- package/dist/lab/requirements.js +54 -0
- package/dist/lab/route-inputs.d.ts +23 -12
- package/dist/lab/route-inputs.js +48 -51
- package/dist/lab/routing.d.ts +19 -24
- package/dist/lab/routing.js +14 -47
- package/dist/lab/run-lab-events.d.ts +6 -11
- package/dist/lab/run-lab-events.js +3 -11
- package/dist/lab/run-lab-homes.d.ts +64 -0
- package/dist/lab/run-lab-homes.js +3 -0
- package/dist/lab/run-lab-options.d.ts +12 -66
- package/dist/lab/run-lab-options.js +45 -275
- package/dist/lab/summary.d.ts +9 -4
- package/dist/lab/summary.js +15 -8
- package/dist/lab/types.d.ts +132 -132
- package/dist/lab/validation.d.ts +15 -15
- package/dist/lab/validation.js +28 -28
- package/dist/lab/warnings.js +20 -19
- package/dist/observer/artifact.d.ts +1 -1
- package/dist/observer/artifact.js +3 -3
- package/dist/observer/data.js +2 -2
- package/dist/observer/render.js +2 -2
- package/dist/observer/run-routes.d.ts +1 -1
- package/dist/observer/run-routes.js +5 -5
- package/dist/observer/serve.d.ts +17 -0
- package/dist/observer/serve.js +34 -3
- package/dist/routes/computer-use/bundle-parts.d.ts +1 -1
- package/dist/routes/computer-use/bundle-parts.js +10 -3
- package/dist/routes/computer-use/bundle.d.ts +4 -11
- package/dist/routes/computer-use/bundle.js +9 -15
- package/dist/routes/computer-use/diagnostics.d.ts +1 -1
- package/dist/routes/computer-use/diagnostics.js +1 -1
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +10 -10
- package/dist/routes/computer-use/e2b-desktop/comms.js +11 -14
- package/dist/routes/computer-use/e2b-desktop/desktop.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -7
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +13 -13
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -11
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +3 -3
- package/dist/routes/computer-use/e2b-desktop/prepare.js +33 -36
- package/dist/routes/computer-use/e2b-desktop/start.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/start.js +24 -23
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/state.js +5 -3
- package/dist/routes/computer-use/e2b-desktop/teardown.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/teardown.js +29 -17
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +19 -43
- package/dist/routes/computer-use/fanout-bundle.d.ts +3 -3
- package/dist/routes/computer-use/fanout-bundle.js +25 -29
- package/dist/routes/computer-use/{fanout-lanes.js → fanout-records.js} +25 -19
- package/dist/routes/computer-use/in-process-desktop.d.ts +3 -10
- package/dist/routes/computer-use/in-process-desktop.js +3 -9
- package/dist/routes/computer-use/live-flush.d.ts +7 -5
- package/dist/routes/computer-use/live-flush.js +19 -27
- package/dist/routes/computer-use/{run-lanes.js → live-phase.js} +12 -11
- package/dist/routes/computer-use/local-tree-pack.d.ts +3 -3
- package/dist/routes/computer-use/local-tree-pack.js +4 -5
- package/dist/routes/computer-use/local-vm.d.ts +11 -8
- package/dist/routes/computer-use/local-vm.js +39 -66
- package/dist/routes/computer-use/participant-desktop.d.ts +8 -23
- package/dist/routes/computer-use/participant-desktop.js +5 -25
- package/dist/routes/computer-use/{lanes.d.ts → participant-execution.d.ts} +10 -10
- package/dist/routes/computer-use/{lanes.js → participant-execution.js} +35 -22
- package/dist/routes/computer-use/participant-facts.d.ts +7 -1
- package/dist/routes/computer-use/participant-facts.js +12 -1
- package/dist/routes/computer-use/participant-model.d.ts +19 -11
- package/dist/routes/computer-use/participant-model.js +49 -25
- package/dist/routes/computer-use/participant-prompt.d.ts +3 -3
- package/dist/routes/computer-use/participant-prompt.js +4 -4
- package/dist/routes/computer-use/participant-runs.d.ts +6 -6
- package/dist/routes/computer-use/participant-runs.js +8 -8
- package/dist/routes/computer-use/plan.d.ts +21 -29
- package/dist/routes/computer-use/plan.js +52 -60
- package/dist/routes/computer-use/preflight.d.ts +3 -5
- package/dist/routes/computer-use/preflight.js +20 -16
- package/dist/routes/computer-use/rerun-selection.js +10 -6
- package/dist/routes/computer-use/result.d.ts +1 -1
- package/dist/routes/computer-use/result.js +40 -30
- package/dist/routes/computer-use/route.d.ts +3 -4
- package/dist/routes/computer-use/route.js +21 -19
- package/dist/routes/computer-use/self-report.d.ts +2 -2
- package/dist/routes/computer-use/self-report.js +4 -4
- package/dist/routes/computer-use/setup.d.ts +8 -14
- package/dist/routes/computer-use/setup.js +96 -72
- package/dist/routes/computer-use/single-bundle.d.ts +8 -11
- package/dist/routes/computer-use/single-bundle.js +20 -25
- package/dist/routes/computer-use/subject-projection.d.ts +5 -7
- package/dist/routes/computer-use/subject-projection.js +20 -19
- package/dist/routes/computer-use/types.d.ts +169 -210
- package/dist/routes/computer-use/types.js +13 -5
- package/dist/routes/preview.js +0 -1
- package/dist/routes/scripted/bundle.d.ts +3 -6
- package/dist/routes/scripted/bundle.js +11 -16
- package/dist/routes/scripted/plan.d.ts +5 -7
- package/dist/routes/scripted/plan.js +6 -4
- package/dist/routes/scripted/result.d.ts +4 -1
- package/dist/routes/scripted/result.js +10 -6
- package/dist/routes/scripted/route.js +10 -11
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +1 -1
- package/dist/routes/scripted/setup.d.ts +3 -2
- package/dist/routes/scripted/setup.js +22 -21
- package/dist/routes/scripted/subject.d.ts +8 -3
- package/dist/routes/scripted/subject.js +9 -5
- package/dist/routes/scripted/surface-records.js +1 -1
- package/dist/routes/scripted/surface-sessions.d.ts +2 -2
- package/dist/routes/scripted/surface-sessions.js +4 -4
- package/dist/routes/scripted/types.d.ts +19 -36
- package/dist/routes/scripted/types.js +1 -2
- package/dist/routes/shared-world/{seat-records.js → bundle-records.js} +8 -8
- package/dist/routes/shared-world/bundle.d.ts +2 -2
- package/dist/routes/shared-world/bundle.js +22 -26
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +4 -4
- package/dist/routes/shared-world/comms.d.ts +5 -4
- package/dist/routes/shared-world/comms.js +28 -41
- package/dist/routes/shared-world/external-public.d.ts +5 -5
- package/dist/routes/shared-world/external-public.js +19 -20
- package/dist/routes/shared-world/handoff.d.ts +4 -4
- package/dist/routes/shared-world/handoff.js +50 -50
- package/dist/routes/shared-world/lobby-code.d.ts +5 -5
- package/dist/routes/shared-world/lobby-code.js +13 -13
- package/dist/routes/shared-world/{seats.d.ts → participant-specs.d.ts} +8 -6
- package/dist/routes/shared-world/{seats.js → participant-specs.js} +43 -48
- package/dist/routes/shared-world/plan.d.ts +2 -6
- package/dist/routes/shared-world/plan.js +1 -2
- package/dist/routes/shared-world/provenance.d.ts +4 -4
- package/dist/routes/shared-world/provenance.js +4 -4
- package/dist/routes/shared-world/provisioned.d.ts +3 -2
- package/dist/routes/shared-world/provisioned.js +46 -40
- package/dist/routes/shared-world/result.js +31 -19
- package/dist/routes/shared-world/route.js +37 -41
- package/dist/routes/shared-world/setup.d.ts +5 -4
- package/dist/routes/shared-world/setup.js +12 -14
- package/dist/routes/shared-world/types.d.ts +53 -126
- package/dist/routes/shared-world/types.js +2 -2
- package/dist/routes/terminal/adapter.d.ts +8 -8
- package/dist/routes/terminal/adapter.js +28 -125
- package/dist/routes/terminal/bundle.d.ts +7 -12
- package/dist/routes/terminal/bundle.js +24 -34
- package/dist/routes/terminal/credentials.d.ts +2 -2
- package/dist/routes/terminal/credentials.js +16 -16
- package/dist/routes/terminal/dry-run.d.ts +1 -1
- package/dist/routes/terminal/dry-run.js +9 -11
- package/dist/routes/terminal/encoding.d.ts +1 -1
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +6 -6
- package/dist/routes/terminal/ledger.js +9 -9
- package/dist/routes/terminal/live-finish.d.ts +1 -2
- package/dist/routes/terminal/live-finish.js +21 -20
- package/dist/routes/terminal/live-sandbox.d.ts +3 -2
- package/dist/routes/terminal/live-sandbox.js +20 -20
- package/dist/routes/terminal/participant-text.d.ts +23 -0
- package/dist/routes/terminal/participant-text.js +165 -0
- package/dist/routes/terminal/plan.d.ts +2 -6
- package/dist/routes/terminal/plan.js +13 -9
- package/dist/routes/terminal/recorder.d.ts +6 -1
- package/dist/routes/terminal/recorder.js +12 -4
- package/dist/routes/terminal/result.js +4 -4
- package/dist/routes/terminal/route.js +26 -26
- package/dist/routes/terminal/runtime.d.ts +3 -2
- package/dist/routes/terminal/runtime.js +3 -3
- package/dist/routes/terminal/sandbox.d.ts +3 -3
- package/dist/routes/terminal/sandbox.js +9 -9
- package/dist/routes/terminal/session.js +16 -14
- package/dist/routes/terminal/token-usage.js +5 -5
- package/dist/routes/terminal/trace.d.ts +5 -8
- package/dist/routes/terminal/trace.js +9 -64
- package/dist/routes/terminal/types.d.ts +85 -93
- package/dist/routes/terminal/types.js +9 -4
- package/dist/run/active-runs.d.ts +13 -0
- package/dist/run/active-runs.js +12 -0
- package/dist/run/bundle-shape.d.ts +2 -1
- package/dist/run/bundle-shape.js +4 -4
- package/dist/run/bundle.d.ts +63 -56
- package/dist/run/bundle.js +9 -8
- package/dist/run/cost-summary.js +3 -2
- package/dist/run/costs.d.ts +6 -6
- package/dist/run/costs.js +10 -10
- package/dist/run/detail.d.ts +5 -5
- package/dist/run/detail.js +6 -6
- package/dist/run/dry-run.js +5 -12
- package/dist/run/{study-files.d.ts → evidence-files.d.ts} +4 -4
- package/dist/run/{study-files.js → evidence-files.js} +5 -5
- package/dist/run/feedback-shape.js +1 -1
- package/dist/run/judge.d.ts +16 -4
- package/dist/run/judge.js +24 -7
- package/dist/run/locate.d.ts +2 -0
- package/dist/run/locate.js +3 -1
- package/dist/run/outcomes.d.ts +3 -3
- package/dist/run/outcomes.js +3 -3
- package/dist/run/participant-records.d.ts +2 -2
- package/dist/run/participant-records.js +2 -2
- package/dist/run/paths.js +1 -1
- package/dist/run/pricing.d.ts +19 -9
- package/dist/run/pricing.js +30 -18
- package/dist/run/projection.d.ts +13 -13
- package/dist/run/projection.js +8 -8
- package/dist/run/reclaim.d.ts +6 -0
- package/dist/run/reclaim.js +13 -3
- package/dist/run/results.d.ts +1 -1
- package/dist/run/run-index.d.ts +1 -1
- package/dist/run/run-index.js +11 -11
- package/dist/run/run.d.ts +4 -2
- package/dist/run/run.js +9 -5
- package/dist/run/sandbox-receipts.d.ts +4 -4
- package/dist/run/sandbox-receipts.js +4 -4
- package/dist/run/shared-world-evidence.d.ts +47 -47
- package/dist/run/shared-world-shape.d.ts +3 -3
- package/dist/run/shared-world-shape.js +11 -11
- package/dist/run/stats.d.ts +5 -5
- package/dist/run/stats.js +8 -8
- package/dist/run/status.d.ts +16 -6
- package/dist/run/status.js +31 -8
- package/dist/run/streams.d.ts +26 -19
- package/dist/run/terminal-contract.d.ts +5 -5
- package/dist/run/terminal-contract.js +4 -4
- package/dist/run/transient-comms-secrets.d.ts +5 -0
- package/dist/run/transient-comms-secrets.js +12 -0
- package/dist/run-lab.d.ts +36 -34
- package/dist/run-lab.js +41 -37
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +1 -1
- package/dist/subject/local-tree-archive.d.ts +1 -1
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +2 -2
- package/dist/subject/local-tree.js +1 -1
- package/dist/subject/node-bootstrap.d.ts +1 -1
- package/dist/subject/node-bootstrap.js +4 -4
- package/dist/subject/runtime.js +5 -5
- package/dist/subject/serve.js +1 -1
- package/dist/subject/steps.d.ts +4 -4
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/e2b/cdp-probe.d.ts +2 -2
- package/dist/substrates/e2b/cdp-probe.js +1 -1
- package/dist/substrates/e2b/desktop-browser.d.ts +3 -3
- package/dist/substrates/e2b/desktop-browser.js +4 -4
- package/dist/substrates/e2b/desktop-cdp.d.ts +7 -7
- package/dist/substrates/e2b/desktop-cdp.js +4 -4
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +3 -3
- package/dist/substrates/e2b/desktop-media.js +2 -2
- package/dist/substrates/e2b/sandbox.js +1 -1
- package/dist/substrates/e2b/sdk.js +2 -2
- package/dist/substrates/local/runtime-host.d.ts +2 -0
- package/dist/substrates/local/runtime-host.js +6 -0
- package/dist/tui/actions.d.ts +7 -5
- package/dist/tui/actions.js +18 -9
- package/dist/tui-app.js +42 -42
- package/dist/verify/actor.d.ts +10 -10
- package/dist/verify/actor.js +15 -15
- package/dist/verify/artifacts.d.ts +1 -1
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/costs.d.ts +2 -2
- package/dist/verify/costs.js +2 -2
- package/dist/verify/liveness.d.ts +1 -1
- package/dist/verify/liveness.js +4 -1
- package/dist/verify/rerun.d.ts +1 -1
- package/dist/verify/rerun.js +1 -1
- package/dist/verify/shared-world.js +2 -2
- package/dist/verify/verify.js +6 -6
- package/docs/README.md +1 -1
- package/docs/architecture/actor-contract.md +60 -22
- package/docs/architecture/desktop-sessions.md +9 -9
- package/docs/architecture/external-public-shared-world.md +5 -0
- package/docs/architecture/observer.md +4 -4
- package/docs/architecture/restricted-codex-analysis.md +36 -2
- package/docs/architecture/state-driven-executor.md +4 -5
- package/docs/architecture/task-protocol-support.md +3 -5
- package/docs/architecture/{terminal-product-lane.md → terminal-product-route.md} +24 -16
- package/docs/contracts/run-bundle.md +10 -8
- package/docs/contracts/schemas.md +109 -53
- package/docs/contracts/study-analysis.md +24 -0
- package/docs/decisions/0004-participant-desktops-stay-in-the-route.md +2 -1
- package/docs/product/automatic-analysis.md +1 -0
- package/docs/ramp/README.md +2 -1
- package/package.json +4 -4
- package/skills/humanish/SKILL.md +3 -2
- package/skills/humanish/agents/openai.yaml +1 -1
- package/dist/deprecated.d.ts +0 -90
- package/dist/deprecated.js +0 -106
- package/dist/lab/bag-overrides.d.ts +0 -18
- package/dist/lab/bag-overrides.js +0 -121
- package/dist/routes/computer-use/legacy-lane-spec.d.ts +0 -62
- package/dist/routes/computer-use/legacy-lane-spec.js +0 -39
- /package/dist/routes/computer-use/{fanout-lanes.d.ts → fanout-records.d.ts} +0 -0
- /package/dist/routes/computer-use/{run-lanes.d.ts → live-phase.d.ts} +0 -0
- /package/dist/routes/shared-world/{seat-records.d.ts → bundle-records.d.ts} +0 -0
|
@@ -17,11 +17,10 @@ import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
|
|
|
17
17
|
export async function runDryTerminalLab(args) {
|
|
18
18
|
const { plan, input, cwd, warnings, failed, scope } = args;
|
|
19
19
|
const { product } = plan;
|
|
20
|
-
const hooks = input.hooks ?? {};
|
|
21
20
|
const { evidenceMission, physicalCwd, persona } = await prepareDryPersona({
|
|
22
21
|
plan,
|
|
23
22
|
cwd,
|
|
24
|
-
env:
|
|
23
|
+
env: input.env ?? process.env,
|
|
25
24
|
warnings,
|
|
26
25
|
});
|
|
27
26
|
const started = await scope.startRun({
|
|
@@ -31,7 +30,7 @@ export async function runDryTerminalLab(args) {
|
|
|
31
30
|
mode: "dry-run",
|
|
32
31
|
lab: plan.lab,
|
|
33
32
|
renderReview: renderTerminalReviewMarkdown,
|
|
34
|
-
observer: { open: input.open === true, render:
|
|
33
|
+
observer: { open: input.open === true, render: input.deps?.renderObserver },
|
|
35
34
|
});
|
|
36
35
|
if (!started.ok)
|
|
37
36
|
return failed(started.code, started.message);
|
|
@@ -46,9 +45,8 @@ export async function runDryTerminalLab(args) {
|
|
|
46
45
|
const policies = plan.residual.policies;
|
|
47
46
|
const judgment = judgeTerminal({ dryRun: true, participant: undefined });
|
|
48
47
|
const bundle = buildTerminalProductBundle({
|
|
49
|
-
|
|
48
|
+
run,
|
|
50
49
|
actorId: plan.actor,
|
|
51
|
-
createdAt,
|
|
52
50
|
dryRun: true,
|
|
53
51
|
labId: plan.labId,
|
|
54
52
|
...(plan.title ? { labTitle: plan.title } : {}),
|
|
@@ -65,7 +63,6 @@ export async function runDryTerminalLab(args) {
|
|
|
65
63
|
allowPaymentCredentials: policies?.allowPaymentCredentials ?? false,
|
|
66
64
|
allowGitHubMutation: policies?.allowGitHubMutation ?? false,
|
|
67
65
|
},
|
|
68
|
-
runId,
|
|
69
66
|
source,
|
|
70
67
|
verdict: judgment.verdict,
|
|
71
68
|
});
|
|
@@ -118,9 +115,9 @@ async function prepareDryPersona(args) {
|
|
|
118
115
|
.filter((value) => value.length >= 4);
|
|
119
116
|
const evidenceMission = participantAssignment({ mission }, scrubLiterals(knownSecretValues)).mission;
|
|
120
117
|
const terminalPersona = await resolveTerminalPersona({ plan, cwd, warnings });
|
|
121
|
-
// The composed prompt = mission + persona + public-surface manifest. Only the
|
|
118
|
+
// The composed prompt = mission + persona + public-surface manifest. Only the author mission
|
|
122
119
|
// goes plaintext into evidence (it is public-safe committed lab text); the full composed prompt
|
|
123
|
-
// is recorded as a
|
|
120
|
+
// is recorded as a digest (the safety contract's mission ruling).
|
|
124
121
|
const composedPrompt = composePrompt({
|
|
125
122
|
mission,
|
|
126
123
|
personaLine: terminalPersona.personaLine,
|
|
@@ -133,7 +130,7 @@ async function prepareDryPersona(args) {
|
|
|
133
130
|
}
|
|
134
131
|
/** The declared runtime provenance as a dry-run event; nothing is observed without a sandbox. */
|
|
135
132
|
function runtimeDeclaredEvent(runtime, createdAt) {
|
|
136
|
-
const { version, model, reasoningEffort } = runtime;
|
|
133
|
+
const { version, model, modelSource, reasoningEffort } = runtime;
|
|
137
134
|
return {
|
|
138
135
|
id: "event-terminal-runtime-declared",
|
|
139
136
|
at: createdAt,
|
|
@@ -141,12 +138,13 @@ function runtimeDeclaredEvent(runtime, createdAt) {
|
|
|
141
138
|
type: "terminal-lab.runtime.declared",
|
|
142
139
|
message: redactText(JSON.stringify(declaredRuntimeProvenance({
|
|
143
140
|
...(version === undefined ? {} : { version }),
|
|
144
|
-
|
|
141
|
+
model,
|
|
142
|
+
modelSource,
|
|
145
143
|
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
146
144
|
}))),
|
|
147
145
|
};
|
|
148
146
|
}
|
|
149
|
-
/** Compose the full prompt the agent would run. Bound to evidence by
|
|
147
|
+
/** Compose the full prompt the agent would run. Bound to evidence by digest only. */
|
|
150
148
|
export function composePrompt(args) {
|
|
151
149
|
return [
|
|
152
150
|
args.personaLine,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Does this environment declare a UTF-8 locale? The POSIX variables are checked in the order the C
|
|
3
|
-
* library resolves them (LC_ALL overrides LC_CTYPE overrides LANG).
|
|
3
|
+
* library resolves them (`LC_ALL` overrides `LC_CTYPE` overrides `LANG`).
|
|
4
4
|
*
|
|
5
5
|
* Windows terminals declare none of these and are handled as UTF-8: modern Windows Terminal and
|
|
6
6
|
* PowerShell render it, and the failure this guards against is a Unix locale that says C/POSIX.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Whether this terminal can render the characters we write to it.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// A participant found this (labs/tui-self-study.yaml): a computer-use participant sitting
|
|
4
4
|
// at a stock desktop ran `humanish` and read back `humanish ��� run realistic synthetic personas`.
|
|
5
5
|
// The em dash is three bytes of UTF-8, and a terminal whose locale is not UTF-8 renders each byte
|
|
6
6
|
// as a replacement glyph. Every ASCII character on the same screen was fine, which is exactly the
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const UTF8 = /utf-?8/i;
|
|
13
13
|
/**
|
|
14
14
|
* Does this environment declare a UTF-8 locale? The POSIX variables are checked in the order the C
|
|
15
|
-
* library resolves them (LC_ALL overrides LC_CTYPE overrides LANG).
|
|
15
|
+
* library resolves them (`LC_ALL` overrides `LC_CTYPE` overrides `LANG`).
|
|
16
16
|
*
|
|
17
17
|
* Windows terminals declare none of these and are handled as UTF-8: modern Windows Terminal and
|
|
18
18
|
* PowerShell render it, and the failure this guards against is a Unix locale that says C/POSIX.
|
|
@@ -3,10 +3,10 @@ import type { LabScenarioCaps } from "../../lab/types.js";
|
|
|
3
3
|
import { type CostCategory } from "../../run/terminal-contract.js";
|
|
4
4
|
import type { CostLine, NoSpendProof, TerminalCostLedger } from "./types.js";
|
|
5
5
|
/**
|
|
6
|
-
* Build the spend ledger from the captured session.
|
|
6
|
+
* Build the spend ledger from the captured session. The null discipline (issue #154):
|
|
7
7
|
* - The `provider` line is populated from the actor trace's tokenUsage.costUsd when the trace
|
|
8
|
-
*
|
|
9
|
-
* provider line is `null` =
|
|
8
|
+
* carries it (a measured value, incl. a measured 0). When the trace carries no costUsd, the
|
|
9
|
+
* provider line is `null` = not measured (never guessed to 0 just because no-spend was intended).
|
|
10
10
|
* - product/media/payment are `null` by default: core has no signal for those categories; an
|
|
11
11
|
* adapter may provide one through the shipped costProbe seam.
|
|
12
12
|
* `injectedLines` lets a test or adapter supply known spend for a category,
|
|
@@ -31,13 +31,13 @@ export declare function noSpendNotEstablished(maxUsd: number): string;
|
|
|
31
31
|
* an all-null ledger for a proven $0.
|
|
32
32
|
*/
|
|
33
33
|
export declare function describeMeasuredSpend(ledger: TerminalCostLedger, tokenUsage?: ActorTokenUsage): string;
|
|
34
|
-
/** Derive the no-spend proof from the ledger. It
|
|
34
|
+
/** Derive the no-spend proof from the ledger. It vouches for known-zero lines and
|
|
35
35
|
* explicitly lists the unmeasured (null) lines it cannot vouch for — never claiming zero on null. */
|
|
36
36
|
export declare function buildNoSpendProof(ledger: TerminalCostLedger, maxUsd: number | null, tokenUsage?: ActorTokenUsage): NoSpendProof;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* Fail-closed caps enforcement. Returns a structured violation when a known
|
|
39
39
|
* (measured) spend line exceeds maxUsd, or a known billable-job count exceeds maxJobs. Unknowns
|
|
40
|
-
* (`null`)
|
|
40
|
+
* (`null`) never trip the cap (we cannot claim a violation we did not measure), and they also never
|
|
41
41
|
* grant a green pass: the no-spend proof reports them as unmeasured. maxMinutes is wall-clock and is
|
|
42
42
|
* enforced separately (runWithWallClock); it is not a ledger-derived cap.
|
|
43
43
|
*/
|
|
@@ -2,10 +2,10 @@ import { describeTokenUsage } from "./token-usage.js";
|
|
|
2
2
|
import { round6 } from "../../run/pricing.js";
|
|
3
3
|
import { COST_CATEGORIES } from "../../run/terminal-contract.js";
|
|
4
4
|
/**
|
|
5
|
-
* Build the spend ledger from the captured session.
|
|
5
|
+
* Build the spend ledger from the captured session. The null discipline (issue #154):
|
|
6
6
|
* - The `provider` line is populated from the actor trace's tokenUsage.costUsd when the trace
|
|
7
|
-
*
|
|
8
|
-
* provider line is `null` =
|
|
7
|
+
* carries it (a measured value, incl. a measured 0). When the trace carries no costUsd, the
|
|
8
|
+
* provider line is `null` = not measured (never guessed to 0 just because no-spend was intended).
|
|
9
9
|
* - product/media/payment are `null` by default: core has no signal for those categories; an
|
|
10
10
|
* adapter may provide one through the shipped costProbe seam.
|
|
11
11
|
* `injectedLines` lets a test or adapter supply known spend for a category,
|
|
@@ -47,7 +47,7 @@ export function buildCostLedger(args) {
|
|
|
47
47
|
payment: args.injectedLines?.payment ?? unmeasured("payment"),
|
|
48
48
|
provider: args.injectedLines?.provider ?? providerLine,
|
|
49
49
|
};
|
|
50
|
-
// knownTotalUsd sums
|
|
50
|
+
// knownTotalUsd sums only the non-null lines. A null line contributes nothing and is never
|
|
51
51
|
// coerced to 0 (that would let an unmeasured category masquerade as a measured zero).
|
|
52
52
|
let knownTotalUsd = 0;
|
|
53
53
|
let fullyMeasured = true;
|
|
@@ -98,7 +98,7 @@ export function describeMeasuredSpend(ledger, tokenUsage) {
|
|
|
98
98
|
.filter((part) => part.length > 0)
|
|
99
99
|
.join(" ");
|
|
100
100
|
}
|
|
101
|
-
/** Derive the no-spend proof from the ledger. It
|
|
101
|
+
/** Derive the no-spend proof from the ledger. It vouches for known-zero lines and
|
|
102
102
|
* explicitly lists the unmeasured (null) lines it cannot vouch for — never claiming zero on null. */
|
|
103
103
|
export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
|
|
104
104
|
const knownZeroLines = [];
|
|
@@ -113,8 +113,8 @@ export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
|
|
|
113
113
|
else
|
|
114
114
|
knownNonZeroLines.push(category);
|
|
115
115
|
}
|
|
116
|
-
// satisfied only when every
|
|
117
|
-
// known line must be exactly 0). Unmeasured lines
|
|
116
|
+
// satisfied only when every known line is within the cap (for a no-spend run, maxUsd 0 => every
|
|
117
|
+
// known line must be exactly 0). Unmeasured lines never make it satisfied; they are reported
|
|
118
118
|
// separately as the proof's honest blind spot.
|
|
119
119
|
const cap = maxUsd ?? 0;
|
|
120
120
|
const satisfied = knownNonZeroLines.length === 0 && ledger.knownTotalUsd <= cap;
|
|
@@ -138,9 +138,9 @@ export function buildNoSpendProof(ledger, maxUsd, tokenUsage) {
|
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
141
|
-
*
|
|
141
|
+
* Fail-closed caps enforcement. Returns a structured violation when a known
|
|
142
142
|
* (measured) spend line exceeds maxUsd, or a known billable-job count exceeds maxJobs. Unknowns
|
|
143
|
-
* (`null`)
|
|
143
|
+
* (`null`) never trip the cap (we cannot claim a violation we did not measure), and they also never
|
|
144
144
|
* grant a green pass: the no-spend proof reports them as unmeasured. maxMinutes is wall-clock and is
|
|
145
145
|
* enforced separately (runWithWallClock); it is not a ledger-derived cap.
|
|
146
146
|
*/
|
|
@@ -2,7 +2,7 @@ import type { ActorPersonaRef } from "../../actors/contract.js";
|
|
|
2
2
|
import type { RunBundle } from "../../run/bundle.js";
|
|
3
3
|
import type { RunScope } from "../../run/run.js";
|
|
4
4
|
import type { LiveSandboxInputs, LiveTerminalSandbox } from "./live-sandbox.js";
|
|
5
|
-
import type { RunLiveTerminalSessionArgs,
|
|
5
|
+
import type { RunLiveTerminalSessionArgs, TerminalProductLabResult } from "./types.js";
|
|
6
6
|
type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
|
|
7
7
|
ok: true;
|
|
8
8
|
}>["run"];
|
|
@@ -11,7 +11,6 @@ export interface LiveFinishInputs {
|
|
|
11
11
|
plan: RunLiveTerminalSessionArgs["plan"];
|
|
12
12
|
input: RunLiveTerminalSessionArgs["input"];
|
|
13
13
|
cwd: string;
|
|
14
|
-
hooks: TerminalProductLabHooks;
|
|
15
14
|
sanitize: (text: string) => string;
|
|
16
15
|
nowIso: () => string;
|
|
17
16
|
knownSecretValues: string[];
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { buildRunCostSummary } from "../../run/cost-summary.js";
|
|
4
4
|
import { writeContainedOutputFile } from "../../run/contained-output.js";
|
|
5
5
|
import { validatePreparedRunArtifactPaths, } from "../../run/paths.js";
|
|
6
|
-
import {
|
|
6
|
+
import { estimateAggregatedTurnCost } from "../../run/pricing.js";
|
|
7
7
|
import { normalizeLocalActorTranscript, TERMINAL_EVENTS_ARTIFACT, TERMINAL_LEDGERS_ARTIFACT, TERMINAL_TRANSCRIPT_ARTIFACT, } from "../../run/terminal-contract.js";
|
|
8
8
|
import { applyAdapterExtensionSeam } from "./adapter.js";
|
|
9
9
|
import { buildLiveTerminalProductBundle } from "./bundle.js";
|
|
@@ -22,9 +22,9 @@ function buildLiveTrace(inputs) {
|
|
|
22
22
|
// chunks before any transcript/trace/event artifact is persisted. Check both each stream and
|
|
23
23
|
// the combined event order that the transcript uses; either view can assemble a split value.
|
|
24
24
|
scrubSplitKnownValues(terminalEvents, knownSecretValues, discardedPrefixes);
|
|
25
|
-
// Build the actor trace
|
|
25
|
+
// Build the actor trace first (the cost ledger reads its tokenUsage).
|
|
26
26
|
const normalizedTranscript = normalizeLocalActorTranscript(terminalEvents.map((e) => e.chunk).join(""));
|
|
27
|
-
// Parsed from the
|
|
27
|
+
// Parsed from the full stream: usage records arrive once per turn, and the tail
|
|
28
28
|
// would drop all but the last (#531).
|
|
29
29
|
const terminalTokenUsage = parseTerminalTokenUsage(normalizedTranscript);
|
|
30
30
|
const trace = buildTerminalActorTrace({
|
|
@@ -39,27 +39,30 @@ function buildLiveTrace(inputs) {
|
|
|
39
39
|
terminalEvents,
|
|
40
40
|
commandLog,
|
|
41
41
|
transcriptTail: tailOf(normalizedTranscript),
|
|
42
|
+
participant: inputs.recorder.participantText.finish(),
|
|
42
43
|
runtimeAuth: runtimeEnv.mode,
|
|
43
44
|
runtime,
|
|
44
45
|
...(terminalTokenUsage === undefined ? {} : { tokenUsage: terminalTokenUsage }),
|
|
45
46
|
});
|
|
46
|
-
//
|
|
47
|
-
|
|
47
|
+
// Priced from the model the route passed to Codex. turn.completed sums a turn's requests, so the
|
|
48
|
+
// estimate uses base rates and says so.
|
|
49
|
+
trace.estimatedCost = estimateAggregatedTurnCost(trace.tokenUsage, runtime.requestedModel);
|
|
48
50
|
return { normalizedTranscript, trace };
|
|
49
51
|
}
|
|
50
52
|
async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
|
|
51
|
-
const {
|
|
53
|
+
const { runtime, session } = inputs;
|
|
54
|
+
const costProbe = inputs.input.deps?.costProbe;
|
|
52
55
|
const { caps } = inputs.plan;
|
|
53
56
|
const { maxUsd } = caps;
|
|
54
57
|
const runPaths = inputs.run.paths;
|
|
55
58
|
const { recordLifecycle, lifecycle, commandLog, interventions, terminalEvents } = inputs.recorder;
|
|
56
59
|
// --- Spend ledger + no-spend proof + full caps enforcement (fail-closed). ---
|
|
57
|
-
// The cost ledger is
|
|
58
|
-
// tokenUsage.costUsd when present (else null =
|
|
59
|
-
// default (core has no signal). The costProbe hook lets tests or adapters inject
|
|
60
|
+
// The cost ledger is derived, with the null discipline: provider spend from the trace's
|
|
61
|
+
// tokenUsage.costUsd when present (else null = not measured), product/media/payment null by
|
|
62
|
+
// default (core has no signal). The costProbe hook lets tests or adapters inject known
|
|
60
63
|
// spend to exercise the fail-closed cap without a real billable run.
|
|
61
|
-
const injectedLines =
|
|
62
|
-
if (
|
|
64
|
+
const injectedLines = costProbe?.(trace.tokenUsage?.costUsd === undefined ? {} : { tokenCostUsd: trace.tokenUsage.costUsd });
|
|
65
|
+
if (costProbe)
|
|
63
66
|
await validatePreparedRunArtifactPaths(runPaths);
|
|
64
67
|
const cost = buildCostLedger({
|
|
65
68
|
...(trace.tokenUsage?.costUsd === undefined ? {} : { tokenCostUsd: trace.tokenUsage.costUsd }),
|
|
@@ -74,9 +77,9 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
|
|
|
74
77
|
: `No-spend proof satisfied on the measured lines for maxUsd=${maxUsd ?? "null"}.`;
|
|
75
78
|
const measuredSpend = describeMeasuredSpend(cost, trace.tokenUsage);
|
|
76
79
|
recordLifecycle("terminal-lab.cost.measured", `Cost ledger: known total ${cost.knownTotalUsd} USD${cost.fullyMeasured ? " (fully measured)" : " (lower bound)"}.${measuredSpend.length > 0 ? ` ${measuredSpend}` : ""} ${proofVerdict}`);
|
|
77
|
-
//
|
|
80
|
+
// Fail-closed caps enforcement: if a known spend line exceeds maxUsd (or a
|
|
78
81
|
// known job count exceeds maxJobs), the run fails closed — never a green result. Unknowns (null)
|
|
79
|
-
//
|
|
82
|
+
// never trip the cap (we cannot claim a violation we did not measure) but never grant a pass
|
|
80
83
|
// either (the no-spend proof reports them as unmeasured). maxMinutes is already wall-clock-
|
|
81
84
|
// enforced above. A blown cap is an execution failure: the agent's own status stays the
|
|
82
85
|
// verdict, and the result's ok is false.
|
|
@@ -91,7 +94,7 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
|
|
|
91
94
|
runtime,
|
|
92
95
|
lifecycle,
|
|
93
96
|
commandLog,
|
|
94
|
-
interventions, //
|
|
97
|
+
interventions, // Always present, and always empty while no assisted-input path ships.
|
|
95
98
|
cleanup: session.cleanup,
|
|
96
99
|
cost,
|
|
97
100
|
noSpendProof,
|
|
@@ -102,11 +105,11 @@ async function settleLiveLedgers(inputs, trace, normalizedTranscript) {
|
|
|
102
105
|
export async function finishLiveTerminalSession(inputs) {
|
|
103
106
|
const { normalizedTranscript, trace } = buildLiveTrace(inputs);
|
|
104
107
|
const { cost, noSpendProof, capFailure, ledgers } = await settleLiveLedgers(inputs, trace, normalizedTranscript);
|
|
105
|
-
const { plan, input, cwd,
|
|
108
|
+
const { plan, input, cwd, sanitize } = inputs;
|
|
106
109
|
const { product, caps } = plan;
|
|
107
110
|
const policies = plan.residual.policies;
|
|
108
111
|
const { runtimeEnv, persona, mission, run, source, warnings, session } = inputs;
|
|
109
|
-
const { runId,
|
|
112
|
+
const { runId, paths: runPaths } = run;
|
|
110
113
|
// One judgment, after a blown cap has overridden the session: the bundle's verdict (and so
|
|
111
114
|
// status.json's outcome) and the result's ok both read it.
|
|
112
115
|
const participant = terminalParticipantFacts(trace, session.error);
|
|
@@ -120,9 +123,8 @@ export async function finishLiveTerminalSession(inputs) {
|
|
|
120
123
|
...(desktops === undefined ? {} : { desktops }),
|
|
121
124
|
});
|
|
122
125
|
const bundle = buildLiveTerminalProductBundle({
|
|
123
|
-
|
|
126
|
+
run,
|
|
124
127
|
actorId: plan.actor,
|
|
125
|
-
createdAt,
|
|
126
128
|
labId: plan.labId,
|
|
127
129
|
...(plan.title ? { labTitle: plan.title } : {}),
|
|
128
130
|
mission: sanitize(mission),
|
|
@@ -138,7 +140,6 @@ export async function finishLiveTerminalSession(inputs) {
|
|
|
138
140
|
allowPaymentCredentials: policies?.allowPaymentCredentials ?? false,
|
|
139
141
|
allowGitHubMutation: policies?.allowGitHubMutation ?? false,
|
|
140
142
|
},
|
|
141
|
-
runId,
|
|
142
143
|
source,
|
|
143
144
|
trace,
|
|
144
145
|
ledgers,
|
|
@@ -154,7 +155,7 @@ export async function finishLiveTerminalSession(inputs) {
|
|
|
154
155
|
// through foldScorerFailures below. Adapter payloads pass the same scrub and redaction as the
|
|
155
156
|
// rest of the bundle, and the bundle verifier checks them downstream.
|
|
156
157
|
const scorer = await applyAdapterExtensionSeam({
|
|
157
|
-
|
|
158
|
+
scorer: input.scorer,
|
|
158
159
|
bundle,
|
|
159
160
|
trace,
|
|
160
161
|
ledgers,
|
|
@@ -4,7 +4,8 @@ import type { RunScope } from "../../run/run.js";
|
|
|
4
4
|
import type { buildRuntimeAuth, buildSandboxMetadata } from "./credentials.js";
|
|
5
5
|
import type { createTerminalRecorder } from "./recorder.js";
|
|
6
6
|
import { type declaredRuntimeProvenance } from "./runtime.js";
|
|
7
|
-
import { type LiveTerminalPlan, type TerminalLedgers
|
|
7
|
+
import { type LiveTerminalPlan, type TerminalLedgers } from "./types.js";
|
|
8
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
8
9
|
type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
|
|
9
10
|
ok: true;
|
|
10
11
|
}>["run"];
|
|
@@ -12,7 +13,7 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
|
|
|
12
13
|
export interface LiveSandboxInputs {
|
|
13
14
|
plan: LiveTerminalPlan;
|
|
14
15
|
cwd: string;
|
|
15
|
-
|
|
16
|
+
deps: LabDeps;
|
|
16
17
|
now: () => number;
|
|
17
18
|
nowIso: () => string;
|
|
18
19
|
sanitize: (text: string) => string;
|
|
@@ -52,13 +52,13 @@ export class LiveTerminalSandbox {
|
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
54
|
async acquire() {
|
|
55
|
-
const { plan,
|
|
55
|
+
const { plan, deps, now, sanitize, runtimeEnv, e2bApiKey, runPaths, metadata } = this.inputs;
|
|
56
56
|
const { warnings } = this.inputs;
|
|
57
57
|
const { recordLifecycle } = this.inputs.recorder;
|
|
58
58
|
const { requestTimeoutMs, sandboxTimeoutMs } = this;
|
|
59
59
|
// Declared egress allowlist, or undefined for the historical unrestricted default (#538).
|
|
60
60
|
const egressAllow = plan.egressAllow;
|
|
61
|
-
const sandboxModule = await (
|
|
61
|
+
const sandboxModule = await (deps.desktopModule ?? loadE2BDesktopModule)();
|
|
62
62
|
this.module = sandboxModule;
|
|
63
63
|
await validatePreparedRunArtifactPaths(runPaths);
|
|
64
64
|
// No sandbox-global env in either mode. In openai-egress, only this host-side SDK request
|
|
@@ -130,7 +130,7 @@ export class LiveTerminalSandbox {
|
|
|
130
130
|
const { recordLifecycle } = this.inputs.recorder;
|
|
131
131
|
const { requestTimeoutMs } = this;
|
|
132
132
|
// --- Runtime bootstrap: no runtime env; openai-egress proxy capability is already available. ---
|
|
133
|
-
// The stock desktop needs Node/npm on PATH before npx can run Codex. Reuse a working
|
|
133
|
+
// The stock desktop needs Node/npm on `PATH` before npx can run Codex. Reuse a working
|
|
134
134
|
// installation or install the pinned official binary after checksum verification (#674).
|
|
135
135
|
// No raw runtime key touches this step; the egress proxy, when selected, is already available.
|
|
136
136
|
const bootstrapStartedAt = now();
|
|
@@ -152,7 +152,7 @@ export class LiveTerminalSandbox {
|
|
|
152
152
|
? `Runtime bootstrap FAILED after ${bootstrapDurationMs}ms: ${bootstrapError}. codex exec runs via npx and needs Node/npm present; the participant fails closed rather than attempting an exec with no runtime.`
|
|
153
153
|
: `Runtime bootstrap ensured Node/npm present in ${bootstrapDurationMs}ms (codex exec runs via npx).`);
|
|
154
154
|
if (bootstrapError) {
|
|
155
|
-
// Fail closed as a structured
|
|
155
|
+
// Fail closed as a structured route status (never a raw throw): no codex exec is attempted
|
|
156
156
|
// without a proven runtime; this mirrors the exec-error status assignment below so the
|
|
157
157
|
// bundle and verify surface the failure the same way.
|
|
158
158
|
this.status = "failed";
|
|
@@ -185,7 +185,7 @@ export class LiveTerminalSandbox {
|
|
|
185
185
|
throw new Error(`Codex version mismatch: requested ${requested}, observed ${observed}.`);
|
|
186
186
|
}
|
|
187
187
|
runtime.versionStatus = "verified";
|
|
188
|
-
recordLifecycle("terminal-lab.runtime.version", `Codex requested ${runtime.requestedVersion}, observed ${observed}; exact version selected for execution. Model ${runtime.requestedModel ?? "
|
|
188
|
+
recordLifecycle("terminal-lab.runtime.version", `Codex requested ${runtime.requestedVersion}, observed ${observed}; exact version selected for execution. Model ${runtime.requestedModel ?? "unrecorded"} (${runtime.modelStatus}); reasoning effort ${runtime.requestedReasoningEffort ?? "runtime default (unobserved)"}.`);
|
|
189
189
|
}
|
|
190
190
|
catch (error) {
|
|
191
191
|
runtime.versionStatus = "failed";
|
|
@@ -205,15 +205,15 @@ export class LiveTerminalSandbox {
|
|
|
205
205
|
const { requestTimeoutMs } = this;
|
|
206
206
|
// --- Optional product setup (no runtime env), before the Codex exec. ---
|
|
207
207
|
// Same channel and same guarantees as the runtime bootstrap above: no runtime key touches it,
|
|
208
|
-
// and a failure fails the
|
|
209
|
-
// exists so a study can put the participant
|
|
208
|
+
// and a failure fails the run closed rather than handing the agent a half-built world. It
|
|
209
|
+
// exists so a study can put the participant in a prepared project: asking an agent what
|
|
210
210
|
// studies a project contains, in an empty directory, measures the lab and not the product
|
|
211
|
-
// (learned the hard way on the desktop
|
|
211
|
+
// (learned the hard way on the desktop route, labs/tui-self-study.yaml).
|
|
212
212
|
const install = plan.product.install;
|
|
213
213
|
if (install === undefined)
|
|
214
214
|
return true;
|
|
215
215
|
// An optional local file, put on the machine before the install runs, so a study can meet a
|
|
216
|
-
// build that is not published yet.
|
|
216
|
+
// build that is not published yet. It is read and checked here, so nothing is trusted from the
|
|
217
217
|
// manifest: this puts a file from the operator's disk onto a machine an autonomous agent is
|
|
218
218
|
// about to drive, so it stays inside the project, must be a regular file, and is size-capped.
|
|
219
219
|
let uploadAssignment = "";
|
|
@@ -239,8 +239,8 @@ export class LiveTerminalSandbox {
|
|
|
239
239
|
});
|
|
240
240
|
const bytes = await readFile(real);
|
|
241
241
|
await this.sandbox.files.write(destination, bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength));
|
|
242
|
-
// Inlined into the command string rather than passed as `envs`: the
|
|
243
|
-
//
|
|
242
|
+
// Inlined into the command string rather than passed as `envs`: the only call on this
|
|
243
|
+
// route that carries envs is the keyed codex exec, and that invariant is worth more than
|
|
244
244
|
// the convenience of a second envs channel.
|
|
245
245
|
uploadAssignment = `export HUMANISH_PRODUCT_UPLOAD=${shellQuote(destination)}; `;
|
|
246
246
|
recordLifecycle("terminal-lab.product.uploaded", `Uploaded ${info.size} bytes to the sandbox in ${Math.max(0, now() - uploadStartedAt)}ms (no runtime env; declared egress auth may already be available).`);
|
|
@@ -300,7 +300,7 @@ export class LiveTerminalSandbox {
|
|
|
300
300
|
prompt: composedPrompt,
|
|
301
301
|
runtimeAuth: runtimeEnv.mode,
|
|
302
302
|
version: runtime.observedVersion,
|
|
303
|
-
|
|
303
|
+
model,
|
|
304
304
|
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
305
305
|
});
|
|
306
306
|
const commandDigest = digestText(codexCommand);
|
|
@@ -342,13 +342,13 @@ export class LiveTerminalSandbox {
|
|
|
342
342
|
at: nowIso(),
|
|
343
343
|
label: "codex-exec",
|
|
344
344
|
commandDigest,
|
|
345
|
-
envNames: Object.keys(runtimeEnv.envs), //
|
|
345
|
+
envNames: Object.keys(runtimeEnv.envs), // Names only: the credential evidence (item 4).
|
|
346
346
|
...(exitCode === undefined ? {} : { exitCode }),
|
|
347
347
|
...(this.timedOut ? { timedOut: true } : {}),
|
|
348
348
|
durationMs,
|
|
349
349
|
});
|
|
350
|
-
// Score by the verdict-nonce marker over the
|
|
351
|
-
// exact same logic the local-actor
|
|
350
|
+
// Score by the verdict-nonce marker over the scrubbed, redacted and normalized transcript, with
|
|
351
|
+
// the exact same logic the local-actor routes use (extractLocalActorVerdict/normalizeLocalActorTranscript).
|
|
352
352
|
const rawTranscript = terminalEvents.map((e) => e.chunk).join("");
|
|
353
353
|
const normalizedTranscript = normalizeLocalActorTranscript(rawTranscript);
|
|
354
354
|
const markerStatus = extractLocalActorVerdict(normalizedTranscript, verdictNonce);
|
|
@@ -378,8 +378,8 @@ export class LiveTerminalSandbox {
|
|
|
378
378
|
}
|
|
379
379
|
else {
|
|
380
380
|
// No nonce-verified verdict: the agent did not (credibly) report a terminal status. A run
|
|
381
|
-
// that exited 0 but printed no verified marker is
|
|
382
|
-
// evidence
|
|
381
|
+
// that exited 0 but printed no verified marker is blocked evidence: the failure is the
|
|
382
|
+
// evidence, and it stays structurally verifiable.
|
|
383
383
|
this.status = "blocked";
|
|
384
384
|
this.completionReason = "gave_up";
|
|
385
385
|
this.reason = `codex exec exit=${exitCode ?? "null"} but no nonce-verified HUMANISH_ACTOR_VERDICT marker was emitted; recorded as blocked (the missing verdict is the evidence).`;
|
|
@@ -404,7 +404,7 @@ export class LiveTerminalSandbox {
|
|
|
404
404
|
const { now, sanitize, warnings } = this.inputs;
|
|
405
405
|
const { recordLifecycle } = this.inputs.recorder;
|
|
406
406
|
const { requestTimeoutMs } = this;
|
|
407
|
-
// --- Safety contract item 8:
|
|
407
|
+
// --- Safety contract item 8: proven cleanup, by exact id, never Sandbox.list. ---
|
|
408
408
|
this.cleanup = await teardownSandbox({
|
|
409
409
|
allocation: this.allocation,
|
|
410
410
|
sandboxModule: this.module,
|
|
@@ -435,14 +435,14 @@ export class LiveTerminalSandbox {
|
|
|
435
435
|
}
|
|
436
436
|
/** Build the in-sandbox `codex exec` command (non-interactive, JSON, stdin disabled by mechanism). */
|
|
437
437
|
function buildCodexExecCommand(args) {
|
|
438
|
-
//
|
|
438
|
+
// stdin is disabled (item 7), so no heredoc on a wrapper's stdin carries the prompt;
|
|
439
439
|
// the prompt rides as the final positional arg, shell-quoted. codex exec --json runs once and
|
|
440
440
|
// exits (no interactive loop). --skip-git-repo-check: the workdir is a fresh scratch dir.
|
|
441
441
|
// Pinned via npx (never an ambient/preinstalled `codex` binary, which the stock @e2b/desktop
|
|
442
442
|
// image does not ship, per issue #159); npm_config_update_notifier=false silences npx's own
|
|
443
443
|
// update check so it cannot leak into the captured stdout the scorer/redactor parse.
|
|
444
444
|
const quotedPrompt = shellQuote(args.prompt);
|
|
445
|
-
// --dangerously-bypass-approvals-and-sandbox: codex's
|
|
445
|
+
// --dangerously-bypass-approvals-and-sandbox: codex's own inner sandbox is
|
|
446
446
|
// redundant here and blocks the network/file access the study mission needs.
|
|
447
447
|
// The E2B sandbox is the trust boundary (the disposable machine), and exec mode has no
|
|
448
448
|
// interactive approval channel at all.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ActorTraceItem } from "../../actors/contract.js";
|
|
2
|
+
/** What the reader found in the agent's Codex JSON stdout. */
|
|
3
|
+
export interface TerminalParticipantText {
|
|
4
|
+
/** Message and reasoning items, the most recent kept under the aggregate limits, then a notice
|
|
5
|
+
* when older ones were left out. */
|
|
6
|
+
items: ActorTraceItem[];
|
|
7
|
+
/** Distinct agent_message items in the stream, kept or not. */
|
|
8
|
+
messages: number;
|
|
9
|
+
/** Distinct participant items: messages, reasoning, commands, web searches and file changes.
|
|
10
|
+
* Lifecycle, usage, launcher diagnostics and nested command output are not activity. Zero
|
|
11
|
+
* means no recognized item was retained, not that the participant succeeded. */
|
|
12
|
+
participantItems: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read participant text from the raw stdout as the recorder receives it. Source redaction runs on
|
|
16
|
+
* the stored stream and can cut through JSON framing (a redacted URL takes the closing quote with
|
|
17
|
+
* it), so each line is parsed here, in memory, and only decoded text that has passed `sanitize`
|
|
18
|
+
* is kept. The raw bytes are never stored.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createTerminalParticipantReader(sanitize: (text: string) => string): {
|
|
21
|
+
append(raw: string): void;
|
|
22
|
+
finish(): TerminalParticipantText;
|
|
23
|
+
};
|