humanish 0.106.0 → 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 -2
- package/ARCHITECTURE.md +17 -16
- package/CHANGELOG.md +24 -0
- package/CONTEXT.md +42 -39
- package/CONTRIBUTING.md +8 -6
- 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 +31 -4
- package/dist/actors/codex/qualified-versions.js +51 -6
- 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 +10 -8
- package/dist/actors/contract.js +7 -1
- 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.d.ts +2 -0
- package/dist/lab/composition-rules.js +35 -26
- 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 +6 -2
- package/dist/lab/plan-base.js +22 -7
- package/dist/lab/plan-participants.d.ts +5 -5
- package/dist/lab/plan-participants.js +2 -2
- package/dist/lab/plan-types.d.ts +33 -7
- 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/observer-app.html +1 -1
- 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} +14 -13
- 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 +58 -33
- 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 +59 -65
- package/dist/routes/computer-use/preflight.d.ts +6 -11
- package/dist/routes/computer-use/preflight.js +26 -18
- 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 -17
- package/dist/routes/computer-use/setup.js +98 -86
- 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 -211
- package/dist/routes/computer-use/types.js +13 -6
- 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 +11 -6
- 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} +46 -51
- 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 +48 -41
- 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 +4 -2
- package/dist/routes/terminal/live-sandbox.js +25 -21
- 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 +5 -3
- package/dist/routes/terminal/sandbox.js +13 -16
- 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 +7 -1
- package/dist/run/reclaim.js +24 -4
- 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/desktop-session.d.ts +2 -0
- 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.d.ts +2 -0
- package/dist/substrates/e2b/sandbox.js +22 -8
- package/dist/substrates/e2b/sdk.d.ts +12 -1
- package/dist/substrates/e2b/sdk.js +30 -9
- 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 +40 -4
- 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
|
@@ -8,39 +8,39 @@
|
|
|
8
8
|
// live-sandbox.ts and live-finish.ts); a dry plan publishes its contract bundle (dry-run.ts);
|
|
9
9
|
// 4. automatic analysis of a run that published its final bundle.
|
|
10
10
|
//
|
|
11
|
-
//
|
|
12
|
-
// the files each item names, and
|
|
11
|
+
// The safety contract (`docs/goals/terminal-product-lane/goal.md`) is enforced by construction in
|
|
12
|
+
// the files each item names, and checked by the verifier (verify/actor.ts
|
|
13
13
|
// validateTerminalProductEvidence):
|
|
14
|
-
// 1.
|
|
15
|
-
//
|
|
14
|
+
// 1. Explicit key placement. openai-env (default) injects the raw runtime key command-scoped,
|
|
15
|
+
// never through Sandbox.create({envs}). Opt-in openai-egress sends it only in the host-side E2B
|
|
16
16
|
// header transform and passes an inert command placeholder. The proxy is spendable by every
|
|
17
17
|
// sandbox process from creation; this protects the raw key, not provider spending.
|
|
18
18
|
// Enforced in credentials.ts and runtime-auth.ts.
|
|
19
|
-
// 2.
|
|
19
|
+
// 2. Fail-closed cap. The live key is never exercised without scenario.caps in force: maxUsd
|
|
20
20
|
// (default/require 0 = no-spend) + maxMinutes (wall-clock kill of the codex command).
|
|
21
21
|
// Enforced in plan.ts (caps required), live-sandbox.ts and lifetime.ts (the wall clock).
|
|
22
|
-
// 3.
|
|
23
|
-
// author mission. No clone, no private-source access — nothing is git-cloned
|
|
22
|
+
// 3. Public surfaces only. The mission references only subject.product.publicSurfaces + the
|
|
23
|
+
// author mission. No clone, no private-source access — nothing is git-cloned on this route.
|
|
24
24
|
// Enforced in session.ts, which composes the prompt.
|
|
25
|
-
// 4.
|
|
25
|
+
// 4. Deny-by-default credentials. The command envs are built from an allowlist holding only the
|
|
26
26
|
// declared runtime key; GITHUB_TOKEN/GH_TOKEN/payment/deploy/db/media keys are excluded by
|
|
27
27
|
// construction (a banned-name guard also fails closed if one is ever requested).
|
|
28
28
|
// Enforced in credentials.ts.
|
|
29
|
-
// 5.
|
|
29
|
+
// 5. No secret values in evidence. Every captured byte (event stream, transcript, command logs,
|
|
30
30
|
// agent report, metadata) passes scrubKnownValues (literal scrub of the runtime key + any
|
|
31
|
-
// provisioned values, >=4 chars,
|
|
32
|
-
// persisting. The transport is labeled
|
|
31
|
+
// provisioned values, >=4 chars, before truncation), then redactText (shape patterns), before
|
|
32
|
+
// persisting. The transport is labeled exec-stream/snapshot; there is no interactive pty.
|
|
33
33
|
// Enforced in recorder.ts, with the scrubber session.ts builds.
|
|
34
|
-
// 6.
|
|
34
|
+
// 6. Metadata positive allowlist. buildSandboxMetadata(allowlist) is the only way metadata is
|
|
35
35
|
// set; it carries solely non-secret labels (mode/tool/labId/simId/provider/runId).
|
|
36
36
|
// Enforced in credentials.ts.
|
|
37
|
-
// 7.
|
|
38
|
-
// bundle
|
|
37
|
+
// 7. Stdin disabled + interventions ledger. stdin is never wired to the codex command; the
|
|
38
|
+
// bundle always carries an interventions ledger (empty array is valid + required-present).
|
|
39
39
|
// Enforced in live-sandbox.ts (stdin) and recorder.ts (the ledger).
|
|
40
|
-
// 8.
|
|
41
|
-
// proof is
|
|
40
|
+
// 8. Proven cleanup, by id, never account-wide. Sandbox.kill(id) in a finally; the cleanup
|
|
41
|
+
// proof is by exact id: kill(id)'s own found-and-killed boolean, confirmed further by
|
|
42
42
|
// Sandbox.getInfo(id) when the SDK exposes it (a thrown SandboxNotFoundError means gone).
|
|
43
|
-
// humanish
|
|
43
|
+
// humanish never calls Sandbox.list to prove cleanup, so a shared operator key never reaches a
|
|
44
44
|
// sandbox it did not create. A live run that cannot prove teardown fails closed.
|
|
45
45
|
// Enforced in sandbox.ts.
|
|
46
46
|
import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
|
|
@@ -50,18 +50,18 @@ import { runScope } from "../../run/run.js";
|
|
|
50
50
|
import { planTerminalLab } from "./plan.js";
|
|
51
51
|
import { runDryTerminalLab } from "./dry-run.js";
|
|
52
52
|
import { checkLiveTerminalMachine, runLiveTerminalSession } from "./session.js";
|
|
53
|
-
import {
|
|
53
|
+
import { terminalRouteScorer } from "../../lab/adapter-scorer-loader.js";
|
|
54
|
+
import { withLateScorer } from "../../lab/route-inputs.js";
|
|
54
55
|
import { TERMINAL_PRODUCT_LAB_SCHEMA, } from "./types.js";
|
|
55
56
|
/**
|
|
56
57
|
* The config-taking entry point. It plans, returns a refusal with the same envelope and analysis
|
|
57
58
|
* record the route has always returned, and otherwise runs the plan.
|
|
58
59
|
*/
|
|
59
60
|
export async function runTerminalProductLab(options) {
|
|
60
|
-
const { config, dryRun,
|
|
61
|
+
const { config, dryRun, ...input } = options;
|
|
61
62
|
const planned = planTerminalLab(config, {
|
|
62
63
|
dryRun,
|
|
63
|
-
|
|
64
|
-
...(input.hooks === undefined ? {} : { hooks: input.hooks }),
|
|
64
|
+
hasCostProbe: input.deps?.costProbe !== undefined,
|
|
65
65
|
});
|
|
66
66
|
if (planned.ok)
|
|
67
67
|
return runTerminalPlan(planned.plan, input);
|
|
@@ -84,7 +84,7 @@ export function terminalLabRefusal(options, refusal) {
|
|
|
84
84
|
};
|
|
85
85
|
// A refusal starts no run, so a declared or default analysis is recorded as skipped.
|
|
86
86
|
const analysis = resolveAutomaticAnalysis(config.review?.analysis);
|
|
87
|
-
return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options
|
|
87
|
+
return completeAutomaticAnalysis(refused, undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
90
|
* Run a terminal plan. The run scope gives a direct library caller the same run lifetime the CLI
|
|
@@ -106,11 +106,11 @@ export async function admitTerminalPlan(plan, input) {
|
|
|
106
106
|
return { ok: false, outcome: terminalOutcome(admission.result) };
|
|
107
107
|
return {
|
|
108
108
|
ok: true,
|
|
109
|
-
run: async (scorer) => terminalOutcome(await runAdmittedTerminalRun(admission.admitted,
|
|
109
|
+
run: async (scorer) => terminalOutcome(await runAdmittedTerminalRun(admission.admitted, withLateScorer(input, scorer, terminalRouteScorer))),
|
|
110
110
|
};
|
|
111
111
|
}
|
|
112
112
|
function terminalOutcome(result) {
|
|
113
|
-
return { route: "terminal",
|
|
113
|
+
return { route: "terminal", result };
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
116
|
* A live plan's local checks, made outside any run scope. A refusal is the result runTerminalPlan
|
|
@@ -132,7 +132,7 @@ async function runAdmittedTerminalRun(admitted, input) {
|
|
|
132
132
|
return completeTerminalAnalysis(admitted.plan, input, result, finished);
|
|
133
133
|
}
|
|
134
134
|
function completeTerminalAnalysis(plan, input, result, finished) {
|
|
135
|
-
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input
|
|
135
|
+
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
|
|
136
136
|
...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
|
|
137
137
|
preferLargerOutput: plan.analysis?.preferLargerOutput === true,
|
|
138
138
|
});
|
|
@@ -157,7 +157,7 @@ async function runTerminalPlanInScope(admitted, input, scope) {
|
|
|
157
157
|
const cwd = path.resolve(input.cwd);
|
|
158
158
|
const { warnings } = admitted;
|
|
159
159
|
const failed = terminalFailure(admitted.plan, input, warnings);
|
|
160
|
-
//
|
|
160
|
+
// Live path: the real in-sandbox agent session. A separate orchestrator owns the
|
|
161
161
|
// create -> inject (command-scoped) -> run -> capture -> teardown lifecycle so the dry-run path
|
|
162
162
|
// below stays a pure contract builder. It enforces the safety contract by construction (the
|
|
163
163
|
// keyPlacement-routed command-scoped key, the deny-by-default allowlist, the fail-closed cap,
|
|
@@ -6,9 +6,10 @@ export declare function isExactRuntimeVersion(value: unknown): value is string;
|
|
|
6
6
|
/** Captured Codex CLI output: `codex-cli 0.153.3\n`. Other shapes fail closed. */
|
|
7
7
|
export declare function parseTerminalRuntimeVersion(stdout: string): string | undefined;
|
|
8
8
|
export declare function buildRuntimeVersionCommand(requestedVersion?: string): string;
|
|
9
|
-
export declare function buildRuntimeExecPrefix(version: string, model
|
|
9
|
+
export declare function buildRuntimeExecPrefix(version: string, model: string, reasoningEffort?: ReasoningEffort): string;
|
|
10
10
|
export declare function declaredRuntimeProvenance(args: {
|
|
11
11
|
version?: string;
|
|
12
|
-
model
|
|
12
|
+
model: string;
|
|
13
|
+
modelSource: "declared" | "humanish_default";
|
|
13
14
|
reasoningEffort?: ReasoningEffort;
|
|
14
15
|
}): ActorRuntimeProvenance;
|
|
@@ -26,7 +26,7 @@ export function buildRuntimeExecPrefix(version, model, reasoningEffort) {
|
|
|
26
26
|
if (!isExactRuntimeVersion(version))
|
|
27
27
|
throw new Error("Codex execution requires a verified exact runtime version.");
|
|
28
28
|
return (`npm_config_update_notifier=false npx -y ${TERMINAL_RUNTIME_PACKAGE}@${version} exec` +
|
|
29
|
-
|
|
29
|
+
` --model ${shellQuote(model)}` +
|
|
30
30
|
(reasoningEffort === undefined
|
|
31
31
|
? ""
|
|
32
32
|
: ` -c ${shellQuote(`model_reasoning_effort=${JSON.stringify(reasoningEffort)}`)}`));
|
|
@@ -37,8 +37,8 @@ export function declaredRuntimeProvenance(args) {
|
|
|
37
37
|
package: TERMINAL_RUNTIME_PACKAGE,
|
|
38
38
|
requestedVersion: args.version ?? "latest",
|
|
39
39
|
versionStatus: "unobserved",
|
|
40
|
-
|
|
41
|
-
modelStatus: args.
|
|
40
|
+
requestedModel: args.model,
|
|
41
|
+
modelStatus: args.modelSource,
|
|
42
42
|
...(args.reasoningEffort === undefined
|
|
43
43
|
? {}
|
|
44
44
|
: { requestedReasoningEffort: args.reasoningEffort }),
|
|
@@ -2,13 +2,13 @@ import type { OwnedDesktopAllocation } from "../../substrates/desktop-session.js
|
|
|
2
2
|
import { E2BDesktopStartupError, type E2BDesktopModule } from "../../substrates/e2b/sdk.js";
|
|
3
3
|
import type { TerminalLedgers } from "./types.js";
|
|
4
4
|
/**
|
|
5
|
-
* Tear the sandbox down and
|
|
5
|
+
* Tear the sandbox down and prove it by exact id, never by Sandbox.list (humanish must never
|
|
6
6
|
* enumerate the operator's E2B account; see docs/principles/invariants-and-defaults.md). The
|
|
7
7
|
* allocation's release (src/substrates/e2b/sandbox.ts) kills the exact id and reads the answer the
|
|
8
8
|
* same way every route does: true is terminated, false or a not-found error is already gone. That
|
|
9
|
-
* is the
|
|
9
|
+
* is the primary proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
|
|
10
10
|
* a second by-id confirmation that the exact sandbox is gone; a returned SandboxInfo with a live
|
|
11
|
-
* state means teardown is
|
|
11
|
+
* state means teardown is unconfirmed. Never throws: teardown failure is recorded, and the caller
|
|
12
12
|
* fails closed on an unproven teardown.
|
|
13
13
|
*/
|
|
14
14
|
export declare function teardownSandbox(args: {
|
|
@@ -17,6 +17,8 @@ export declare function teardownSandbox(args: {
|
|
|
17
17
|
/** For the Sandbox.getInfo(id) re-check only. */
|
|
18
18
|
sandboxModule: E2BDesktopModule | undefined;
|
|
19
19
|
startupCleanup?: E2BDesktopStartupError["cleanup"];
|
|
20
|
+
/** Why the startup guard's cleanup is unconfirmed, when it knows. */
|
|
21
|
+
startupCleanupDetail?: string | undefined;
|
|
20
22
|
requestTimeoutMs: number;
|
|
21
23
|
sanitize: (text: string) => string;
|
|
22
24
|
recordLifecycle: (event: string, message: string) => void;
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
import { toErrorMessage } from "../../evidence/redaction.js";
|
|
2
2
|
import { E2BDesktopStartupError, isSandboxNotFoundError, } from "../../substrates/e2b/sdk.js";
|
|
3
|
+
import { releaseUnavailableDetail } from "../../substrates/e2b/sandbox.js";
|
|
3
4
|
/**
|
|
4
|
-
* Tear the sandbox down and
|
|
5
|
+
* Tear the sandbox down and prove it by exact id, never by Sandbox.list (humanish must never
|
|
5
6
|
* enumerate the operator's E2B account; see docs/principles/invariants-and-defaults.md). The
|
|
6
7
|
* allocation's release (src/substrates/e2b/sandbox.ts) kills the exact id and reads the answer the
|
|
7
8
|
* same way every route does: true is terminated, false or a not-found error is already gone. That
|
|
8
|
-
* is the
|
|
9
|
+
* is the primary proof. Where the SDK exposes Sandbox.getInfo(id), a thrown SandboxNotFoundError is
|
|
9
10
|
* a second by-id confirmation that the exact sandbox is gone; a returned SandboxInfo with a live
|
|
10
|
-
* state means teardown is
|
|
11
|
+
* state means teardown is unconfirmed. Never throws: teardown failure is recorded, and the caller
|
|
11
12
|
* fails closed on an unproven teardown.
|
|
12
13
|
*/
|
|
13
14
|
export async function teardownSandbox(args) {
|
|
14
|
-
const { allocation, sandboxModule, startupCleanup, requestTimeoutMs, sanitize, recordLifecycle, warnings, } = args;
|
|
15
|
+
const { allocation, sandboxModule, startupCleanup, startupCleanupDetail, requestTimeoutMs, sanitize, recordLifecycle, warnings, } = args;
|
|
15
16
|
if (allocation === undefined || !sandboxModule) {
|
|
16
|
-
// create() can reject
|
|
17
|
-
// that authority and reclaims it before rejecting; the
|
|
17
|
+
// create() can reject after its constructor acquired a handle. The default loader retains
|
|
18
|
+
// that authority and reclaims it before rejecting; the route itself never receives its ID.
|
|
18
19
|
if (startupCleanup === "killed" || startupCleanup === "already_gone") {
|
|
19
20
|
const reason = `desktop startup guard confirmed its acquired sandbox ${startupCleanup === "killed" ? "was killed" : "was already gone"}`;
|
|
20
21
|
recordLifecycle("terminal-lab.cleanup.killed", reason);
|
|
21
22
|
return { killed: true, remaining: 0, reason };
|
|
22
23
|
}
|
|
23
24
|
const reason = startupCleanup === "unconfirmed"
|
|
24
|
-
?
|
|
25
|
+
? `desktop startup guard could not confirm cleanup of its acquired sandbox${startupCleanupDetail === undefined ? "" : ` (${startupCleanupDetail})`}; provider timeout remains the backstop`
|
|
25
26
|
: "create did not return a sandbox; the participant has no acquired handle and cannot establish allocation or cleanup";
|
|
26
27
|
recordLifecycle("terminal-lab.cleanup.unconfirmed", reason);
|
|
27
28
|
return { killed: false, remaining: -1, reason };
|
|
@@ -30,11 +31,7 @@ export async function teardownSandbox(args) {
|
|
|
30
31
|
const released = await allocation.close();
|
|
31
32
|
if (released.status !== "released") {
|
|
32
33
|
if (released.status === "unconfirmed" && released.reason === "release_unavailable") {
|
|
33
|
-
return {
|
|
34
|
-
killed: false,
|
|
35
|
-
remaining: -1,
|
|
36
|
-
reason: "installed @e2b/desktop SDK does not expose Sandbox.kill; server-side kill-on-timeout will reclaim the sandbox",
|
|
37
|
-
};
|
|
34
|
+
return { killed: false, remaining: -1, reason: releaseUnavailableDetail(released.detail) };
|
|
38
35
|
}
|
|
39
36
|
if (released.status === "unconfirmed" && released.reason === "release_failed") {
|
|
40
37
|
const sanitizedError = sanitize(toErrorMessage(released.error));
|
|
@@ -52,12 +49,12 @@ export async function teardownSandbox(args) {
|
|
|
52
49
|
recordLifecycle("terminal-lab.cleanup.unconfirmed", `Sandbox ${sandboxId} ${reason}.`);
|
|
53
50
|
return { killed: false, remaining: -1, reason };
|
|
54
51
|
}
|
|
55
|
-
//
|
|
52
|
+
// By-id verification only, from here down: never Sandbox.list. A released result is itself proof
|
|
56
53
|
// the exact sandbox is gone: terminated when kill(id) found and killed it, already gone when
|
|
57
54
|
// kill(id) answered false or threw not-found (a 404, e.g. the server-side kill-on-timeout raced
|
|
58
55
|
// ahead). Both mean "this id is no longer running." Sandbox.getInfo(id), when the SDK exposes
|
|
59
56
|
// it, adds a second by-id confirmation; the only thing that overturns the release proof is
|
|
60
|
-
// getInfo returning a
|
|
57
|
+
// getInfo returning a live sandbox for this exact id.
|
|
61
58
|
const killNote = released.reason === "terminated"
|
|
62
59
|
? "kill(id) returned true (found and killed)"
|
|
63
60
|
: "kill(id) found the exact sandbox already gone (404)";
|
|
@@ -88,8 +85,8 @@ export async function teardownSandbox(args) {
|
|
|
88
85
|
reason: `reclaimed by id; getInfo(id) confirms the exact sandbox no longer exists (SandboxNotFoundError)`,
|
|
89
86
|
};
|
|
90
87
|
}
|
|
91
|
-
// getInfo(id) failed for a reason
|
|
92
|
-
// no second by-id confirmation is available, so the
|
|
88
|
+
// getInfo(id) failed for a reason other than "not found" (e.g. a transient network error):
|
|
89
|
+
// no second by-id confirmation is available, so the resolved kill(id) call stands as the proof
|
|
93
90
|
// of absence. Never fall back to Sandbox.list.
|
|
94
91
|
const sanitizedError = sanitize(toErrorMessage(error));
|
|
95
92
|
recordLifecycle("terminal-lab.cleanup.killed", `Sandbox ${sandboxId} reclaimed: ${killNote}; getInfo(id) re-verification errored (${sanitizedError}), so kill(id)'s resolved result is the proof.`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
2
|
+
import { missingKeys } from "../../lab/requirements.js";
|
|
2
3
|
import { declaredRuntimeProvenance } from "./runtime.js";
|
|
3
4
|
import { digestText, redactText, scrubLiterals } from "../../evidence/redaction.js";
|
|
4
5
|
import { describeMissingKeys } from "../../keys/key-resolution.js";
|
|
@@ -15,7 +16,7 @@ import { finishLiveTerminalSession } from "./live-finish.js";
|
|
|
15
16
|
* a declared scorer. Returns the runtime key's command-scoped placement, or the refusal.
|
|
16
17
|
*/
|
|
17
18
|
export function checkLiveTerminalMachine(plan, input, warnings) {
|
|
18
|
-
const env = input.
|
|
19
|
+
const env = input.env ?? process.env;
|
|
19
20
|
const { maxUsd } = plan.caps;
|
|
20
21
|
// planTerminalLab refuses a positive maxUsd without a costProbe, so one is present here.
|
|
21
22
|
if (maxUsd > 0) {
|
|
@@ -26,7 +27,8 @@ export function checkLiveTerminalMachine(plan, input, warnings) {
|
|
|
26
27
|
if (!runtimeEnv.ok)
|
|
27
28
|
return runtimeEnv;
|
|
28
29
|
// The sandbox is created with E2B_API_KEY, so a missing key is refused before the run starts.
|
|
29
|
-
|
|
30
|
+
// The runtime key above is the plan's `key-one-of`; E2B_API_KEY is its only `key`.
|
|
31
|
+
if (missingKeys(plan.requirements, env).length > 0) {
|
|
30
32
|
return {
|
|
31
33
|
ok: false,
|
|
32
34
|
code: "HUMANISH_TERMINAL_LAB_KEYS_MISSING",
|
|
@@ -46,9 +48,9 @@ export async function runLiveTerminalSession(args) {
|
|
|
46
48
|
const { plan, input, cwd, warnings, failed, scope, runtimeEnv } = args;
|
|
47
49
|
const { actor, product } = plan;
|
|
48
50
|
const { maxUsd, maxMinutes } = plan.caps;
|
|
49
|
-
const
|
|
50
|
-
const env =
|
|
51
|
-
const now =
|
|
51
|
+
const deps = input.deps ?? {};
|
|
52
|
+
const env = input.env ?? process.env;
|
|
53
|
+
const now = deps.now ?? (() => Date.now());
|
|
52
54
|
const nowIso = () => new Date(now()).toISOString();
|
|
53
55
|
const prepared = await prepareLivePrompt({ plan, cwd, runtimeEnv, env, warnings });
|
|
54
56
|
const { mission, physicalCwd, persona, composedPrompt, verdictNonce } = prepared;
|
|
@@ -61,7 +63,7 @@ export async function runLiveTerminalSession(args) {
|
|
|
61
63
|
mode: "live",
|
|
62
64
|
lab: plan.lab,
|
|
63
65
|
renderReview: renderTerminalReviewMarkdown,
|
|
64
|
-
observer: { open: input.open === true, render:
|
|
66
|
+
observer: { open: input.open === true, render: deps.renderObserver },
|
|
65
67
|
now,
|
|
66
68
|
});
|
|
67
69
|
if (!started.ok)
|
|
@@ -77,17 +79,18 @@ export async function runLiveTerminalSession(args) {
|
|
|
77
79
|
const e2bApiKey = env.E2B_API_KEY?.trim() ?? "";
|
|
78
80
|
// The ledgers + capture buffers, mutated through the live lifecycle.
|
|
79
81
|
const recorder = createTerminalRecorder({ nowIso, sanitize, knownSecretValues });
|
|
80
|
-
const { version, model, reasoningEffort } = plan.runtime;
|
|
82
|
+
const { version, model, modelSource, reasoningEffort } = plan.runtime;
|
|
81
83
|
const runtime = declaredRuntimeProvenance({
|
|
82
84
|
...(version === undefined ? {} : { version }),
|
|
83
|
-
|
|
85
|
+
model: sanitize(model),
|
|
86
|
+
modelSource,
|
|
84
87
|
...(reasoningEffort === undefined ? {} : { reasoningEffort }),
|
|
85
88
|
});
|
|
86
89
|
recorder.recordLifecycle("terminal-lab.run.created", `Created live terminal-product run ${runId} (actor ${actor}, product ${product.name}). Caps: maxUsd=${maxUsd}, maxMinutes=${maxMinutes}. Subject provenance UNPINNED (public surfaces only).`);
|
|
87
90
|
const session = new LiveTerminalSandbox({
|
|
88
91
|
plan,
|
|
89
92
|
cwd,
|
|
90
|
-
|
|
93
|
+
deps,
|
|
91
94
|
now,
|
|
92
95
|
nowIso,
|
|
93
96
|
sanitize,
|
|
@@ -122,7 +125,6 @@ export async function runLiveTerminalSession(args) {
|
|
|
122
125
|
plan,
|
|
123
126
|
input,
|
|
124
127
|
cwd,
|
|
125
|
-
hooks,
|
|
126
128
|
sanitize,
|
|
127
129
|
nowIso,
|
|
128
130
|
knownSecretValues,
|
|
@@ -144,7 +146,7 @@ export async function runLiveTerminalSession(args) {
|
|
|
144
146
|
async function prepareLivePrompt(args) {
|
|
145
147
|
const { plan, cwd, runtimeEnv, env, warnings } = args;
|
|
146
148
|
const { product } = plan;
|
|
147
|
-
// Compose the prompt from
|
|
149
|
+
// Compose the prompt from public surfaces and the author mission alone (safety contract item 3).
|
|
148
150
|
// Inject a per-run verdict nonce: the agent echoes HUMANISH_ACTOR_VERDICT=<status>
|
|
149
151
|
// HUMANISH_ACTOR_NONCE=<nonce>; the scorer verifies the nonce so replayed text cannot forge it.
|
|
150
152
|
const mission = plan.mission ?? defaultMission(product.name);
|
|
@@ -158,8 +160,8 @@ async function prepareLivePrompt(args) {
|
|
|
158
160
|
verdictNonce,
|
|
159
161
|
});
|
|
160
162
|
const promptDigest = digestText(composedPrompt);
|
|
161
|
-
// --- Safety contract item 5: literal-scrub
|
|
162
|
-
// The runtime key value (+ any other provisioned value) is scrubbed by
|
|
163
|
+
// --- Safety contract item 5: literal-scrub every known value, then pattern-redact, at the source. ---
|
|
164
|
+
// The runtime key value (+ any other provisioned value) is scrubbed by literal match before
|
|
163
165
|
// anything persists (a key has no detectable "shape" if it is an arbitrary token); redactText is
|
|
164
166
|
// the second pass for secret-SHAPED content. Applied PRE-truncation so a cut can never split a
|
|
165
167
|
// value past the scrubber.
|
|
@@ -177,7 +179,7 @@ async function prepareLivePrompt(args) {
|
|
|
177
179
|
sanitize,
|
|
178
180
|
};
|
|
179
181
|
}
|
|
180
|
-
/** Compose the live prompt:
|
|
182
|
+
/** Compose the live prompt: public surfaces + author mission + the verdict-nonce marker contract. */
|
|
181
183
|
function composeLivePrompt(args) {
|
|
182
184
|
return [
|
|
183
185
|
args.personaLine,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// Provider token accounting for the terminal
|
|
1
|
+
// Provider token accounting for the terminal route (#531).
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// The gap this closes: a live terminal run reported `cost.lines.provider = null` with source
|
|
4
4
|
// "unmeasured", and the no-spend proof then read `satisfied: true` for `maxUsd: 0` on a run that
|
|
5
5
|
// had demonstrably consumed hundreds of thousands of provider tokens. The statement was honest
|
|
6
6
|
// (it listed provider as unmeasured) but it conflated two very different states: having no signal
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
// {"type":"turn.completed","usage":{"input_tokens":201536,"cached_input_tokens":170558,
|
|
11
11
|
// "cache_write_input_tokens":30951,"output_tokens":2283,"reasoning_output_tokens":902}}
|
|
12
12
|
//
|
|
13
|
-
// So the
|
|
14
|
-
// out of this module deliberately: pricing lives in src/run/pricing.ts, and the terminal
|
|
13
|
+
// So the route can record a measured token fact even when it cannot record a priced one. Rates stay
|
|
14
|
+
// out of this module deliberately: pricing lives in src/run/pricing.ts, and the terminal route has no
|
|
15
15
|
// real model id to price against (it records `model: "codex"`), so the honest output is
|
|
16
16
|
// tokens-known-rate-unknown rather than a guessed dollar figure.
|
|
17
|
-
// Bounded to a single line on purpose. `[^}]*` would run past a
|
|
17
|
+
// Bounded to a single line on purpose. `[^}]*` would run past a truncated record's missing brace
|
|
18
18
|
// and swallow the next, valid record's body, silently dropping a real turn from the count.
|
|
19
19
|
const USAGE_RE = /"type"\s*:\s*"turn\.completed"\s*,\s*"usage"\s*:\s*(\{[^}\n]*\})/g;
|
|
20
20
|
function num(value) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ActorCompletionReason, ActorPersonaRef, ActorRuntimeProvenance, ActorStatus, ActorTokenUsage, ActorTrace } from "../../actors/contract.js";
|
|
2
2
|
import type { LabRuntimeAuth } from "../../lab/types.js";
|
|
3
|
+
import type { TerminalParticipantText } from "./participant-text.js";
|
|
3
4
|
import { type CommandLogRecord, type TerminalEventRecord } from "./types.js";
|
|
4
5
|
/**
|
|
5
6
|
* Per-chunk sanitization cannot recognize a value split across deliveries. Redact those complete
|
|
@@ -10,9 +11,9 @@ export declare function scrubSplitKnownValues(events: TerminalEventRecord[], kno
|
|
|
10
11
|
/** Redacted, ellipsis-prefixed tail of a captured stream/log for a message field. */
|
|
11
12
|
export declare function tailOf(text: string): string;
|
|
12
13
|
/**
|
|
13
|
-
* Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (lane
|
|
14
|
+
* Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
|
|
14
15
|
* "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
|
|
15
|
-
* guard (a real run bumps them; a no-op is caught). No screenshots on this
|
|
16
|
+
* guard (a real run bumps them; a no-op is caught). No screenshots on this route.
|
|
16
17
|
*/
|
|
17
18
|
export declare function buildTerminalActorTrace(args: {
|
|
18
19
|
persona: ActorPersonaRef;
|
|
@@ -31,10 +32,6 @@ export declare function buildTerminalActorTrace(args: {
|
|
|
31
32
|
/** Runtime-turn aggregate usage parsed from the exec stream (#531). Absent when the stream
|
|
32
33
|
* carried no usage record, which stays distinct from a measured zero. */
|
|
33
34
|
tokenUsage?: ActorTokenUsage;
|
|
35
|
+
/** The agent's own text and activity, read from the raw stdout as it arrived. */
|
|
36
|
+
participant: TerminalParticipantText;
|
|
34
37
|
}): ActorTrace;
|
|
35
|
-
/** Count distinct participant items in the retained Codex JSON stdout stream.
|
|
36
|
-
* The caller supplies stdout only, after transport reconciliation and redaction.
|
|
37
|
-
* Lifecycle, usage, launcher diagnostics, and nested command output are not activity.
|
|
38
|
-
* Zero means no recognized item was retained, not that the participant succeeded.
|
|
39
|
-
*/
|
|
40
|
-
export declare function countTerminalParticipantItems(stdout: string): number;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ACTOR_TRACE_SCHEMA, TERMINAL_AGENT_CAPABILITIES } from "../../actors/contract.js";
|
|
2
2
|
import { redactedTail } from "../../evidence/redaction.js";
|
|
3
|
-
import { normalizeLocalActorTranscript } from "../../run/terminal-contract.js";
|
|
4
3
|
import { TAIL_CHARS } from "./types.js";
|
|
5
4
|
/**
|
|
6
5
|
* Per-chunk sanitization cannot recognize a value split across deliveries. Redact those complete
|
|
@@ -57,9 +56,9 @@ export function tailOf(text) {
|
|
|
57
56
|
return redactedTail(text, TAIL_CHARS);
|
|
58
57
|
}
|
|
59
58
|
/**
|
|
60
|
-
* Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (lane
|
|
59
|
+
* Project the live terminal session into the provider-neutral humanish.actor-trace.v1 (`lane`
|
|
61
60
|
* "terminal", protocol "terminal-exec"). counts.actions/messages drive the no-engagement honesty
|
|
62
|
-
* guard (a real run bumps them; a no-op is caught). No screenshots on this
|
|
61
|
+
* guard (a real run bumps them; a no-op is caught). No screenshots on this route.
|
|
63
62
|
*/
|
|
64
63
|
export function buildTerminalActorTrace(args) {
|
|
65
64
|
const items = [
|
|
@@ -74,19 +73,7 @@ export function buildTerminalActorTrace(args) {
|
|
|
74
73
|
outputTail: args.transcriptTail,
|
|
75
74
|
},
|
|
76
75
|
})),
|
|
77
|
-
|
|
78
|
-
// narrated SOMETHING — the engagement signal the no-engagement guard reads.
|
|
79
|
-
...(args.terminalEvents.length > 0
|
|
80
|
-
? [
|
|
81
|
-
{
|
|
82
|
-
id: "message-001",
|
|
83
|
-
kind: "message",
|
|
84
|
-
lifecycle: "completed",
|
|
85
|
-
title: "agent terminal output",
|
|
86
|
-
text: args.transcriptTail,
|
|
87
|
-
},
|
|
88
|
-
]
|
|
89
|
-
: []),
|
|
76
|
+
...args.participant.items,
|
|
90
77
|
];
|
|
91
78
|
return {
|
|
92
79
|
schema: ACTOR_TRACE_SCHEMA,
|
|
@@ -113,17 +100,13 @@ export function buildTerminalActorTrace(args) {
|
|
|
113
100
|
...(args.tokenUsage ? { tokenUsage: args.tokenUsage } : {}),
|
|
114
101
|
counts: {
|
|
115
102
|
commands: args.commandLog.length,
|
|
116
|
-
// Unlike the
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
.map((event) => event.chunk)
|
|
122
|
-
.join(""))),
|
|
123
|
-
// actions == executed commands; messages == 1 when the agent produced any output. The
|
|
124
|
-
// no-engagement guard (verify/actor.ts) reads these: a real run bumps them, a no-op is caught.
|
|
103
|
+
// Unlike the actions count, this establishes actual runtime item activity. Stderr and
|
|
104
|
+
// bootstrap commands never count.
|
|
105
|
+
runtimeParticipantItems: args.participant.participantItems,
|
|
106
|
+
// actions == executed commands, so the launcher command alone keeps the no-engagement guard
|
|
107
|
+
// (verify/actor.ts) satisfied; messages == the agent_message items in the stream.
|
|
125
108
|
actions: args.commandLog.length,
|
|
126
|
-
messages: args.
|
|
109
|
+
messages: args.participant.messages,
|
|
127
110
|
terminalEvents: args.terminalEvents.length,
|
|
128
111
|
},
|
|
129
112
|
items,
|
|
@@ -132,41 +115,3 @@ export function buildTerminalActorTrace(args) {
|
|
|
132
115
|
: TERMINAL_AGENT_CAPABILITIES,
|
|
133
116
|
};
|
|
134
117
|
}
|
|
135
|
-
const itemEvents = new Set(["item.started", "item.updated", "item.completed"]);
|
|
136
|
-
const nonempty = (value) => typeof value === "string" && value.trim().length > 0;
|
|
137
|
-
const object = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
138
|
-
/** Count distinct participant items in the retained Codex JSON stdout stream.
|
|
139
|
-
* The caller supplies stdout only, after transport reconciliation and redaction.
|
|
140
|
-
* Lifecycle, usage, launcher diagnostics, and nested command output are not activity.
|
|
141
|
-
* Zero means no recognized item was retained, not that the participant succeeded.
|
|
142
|
-
*/
|
|
143
|
-
export function countTerminalParticipantItems(stdout) {
|
|
144
|
-
const ids = new Set();
|
|
145
|
-
for (const line of stdout.split("\n")) {
|
|
146
|
-
let event;
|
|
147
|
-
try {
|
|
148
|
-
event = JSON.parse(line);
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (!object(event) ||
|
|
154
|
-
typeof event.type !== "string" ||
|
|
155
|
-
!itemEvents.has(event.type) ||
|
|
156
|
-
!object(event.item))
|
|
157
|
-
continue;
|
|
158
|
-
const item = event.item;
|
|
159
|
-
if (!nonempty(item.id))
|
|
160
|
-
continue;
|
|
161
|
-
const active = ((item.type === "agent_message" || item.type === "reasoning") && nonempty(item.text)) ||
|
|
162
|
-
(item.type === "command_execution" && nonempty(item.command)) ||
|
|
163
|
-
(item.type === "web_search" &&
|
|
164
|
-
(nonempty(item.query) || (object(item.action) && nonempty(item.action.type)))) ||
|
|
165
|
-
(item.type === "file_change" &&
|
|
166
|
-
Array.isArray(item.changes) &&
|
|
167
|
-
item.changes.some((change) => object(change) && nonempty(change.path) && nonempty(change.kind)));
|
|
168
|
-
if (active)
|
|
169
|
-
ids.add(item.id);
|
|
170
|
-
}
|
|
171
|
-
return ids.size;
|
|
172
|
-
}
|