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
package/dist/run/projection.d.ts
CHANGED
|
@@ -40,11 +40,11 @@ export interface LabExpectation {
|
|
|
40
40
|
costUnknown: number;
|
|
41
41
|
}
|
|
42
42
|
/**
|
|
43
|
-
* Derive what to expect from a lab's own history. Only
|
|
43
|
+
* Derive what to expect from a lab's own history. Only finished runs count: an interrupted run's
|
|
44
44
|
* duration is the length of an accident, not of a study, and including it would quietly bias the
|
|
45
45
|
* estimate the operator uses to decide whether to press Start.
|
|
46
46
|
*
|
|
47
|
-
*
|
|
47
|
+
* The mode matters: mixing modes produces a false figure. A dry run spends nothing and
|
|
48
48
|
* takes no time, so a median over nine dry runs and one live one reports that a live run is free —
|
|
49
49
|
* next to a control that spends money. Pass the mode the figure is about; omit it only for a
|
|
50
50
|
* summary that is not attached to an action.
|
|
@@ -59,7 +59,7 @@ export declare function expectationLine(expectation: LabExpectation): string;
|
|
|
59
59
|
/**
|
|
60
60
|
* The one line a lab may say about itself, wherever it is shown.
|
|
61
61
|
*
|
|
62
|
-
* Prefers
|
|
62
|
+
* Prefers live figures: cost and duration are what someone reads before spending, and a median
|
|
63
63
|
* diluted by dry runs reports a live study as cheaper and faster than it has ever been. With no
|
|
64
64
|
* live history it reports the count and claims nothing about time or money — which is why this is
|
|
65
65
|
* shared rather than reimplemented per surface, since the two disagreeing is the whole failure.
|
|
@@ -104,15 +104,15 @@ export declare function livenessLabel(entry: Pick<RunIndexEntry, "liveness" | "v
|
|
|
104
104
|
/** A lab as the labs list shows it: what is declared, joined to what actually happened. */
|
|
105
105
|
export interface LabRow {
|
|
106
106
|
/**
|
|
107
|
-
* Stable identity for
|
|
107
|
+
* Stable identity for this row. A manifest's path when it has one, else the lab id, because two
|
|
108
108
|
* manifests can declare the same id, and keying rows by id makes them collapse into a pair of
|
|
109
109
|
* indistinguishable duplicates.
|
|
110
110
|
*/
|
|
111
111
|
key: string;
|
|
112
|
-
/** The declared id. Run history attributes to this, so it is
|
|
112
|
+
/** The declared id. Run history attributes to this, so it is not unique across manifests. */
|
|
113
113
|
labId: string;
|
|
114
114
|
/**
|
|
115
|
-
* The handle an operator would actually type. Lab resolution is by
|
|
115
|
+
* The handle an operator would actually type. Lab resolution is by filename, so the manifest
|
|
116
116
|
* `\`.humanish/labs/persona-contrast-live.yaml\`` is reached as `persona-contrast-live` even when
|
|
117
117
|
* the id inside it says something else.
|
|
118
118
|
*/
|
|
@@ -120,25 +120,25 @@ export interface LabRow {
|
|
|
120
120
|
/** The manifest's own title, when it has one. */
|
|
121
121
|
title?: string;
|
|
122
122
|
/**
|
|
123
|
-
* The shortest label that is
|
|
123
|
+
* The shortest label that is unique among the rows it is listed with: the title when no other
|
|
124
124
|
* lab shares it, else the filename, else the full path. A list is only navigable if every row can
|
|
125
125
|
* be told from every other one, and a title is not guaranteed to be distinct — two manifests in
|
|
126
|
-
* this repo carry the same title
|
|
126
|
+
* this repo carry the same title and the same declared id, differing only by filename.
|
|
127
127
|
*/
|
|
128
128
|
label: string;
|
|
129
|
-
/** The manifest's own words, for the list to say what this study
|
|
129
|
+
/** The manifest's own words, for the list to say what this study is. */
|
|
130
130
|
description?: string;
|
|
131
131
|
/** Repo-relative manifest path, absent for a lab known only from run history. */
|
|
132
132
|
path?: string;
|
|
133
133
|
origin?: "committed" | "ignored" | "explicit";
|
|
134
134
|
/**
|
|
135
|
-
* False for a lab that has runs but
|
|
135
|
+
* False for a lab that has runs but no manifest here: renamed, deleted, or run from a path that
|
|
136
136
|
* is gone. Its runs are still evidence and must stay reachable, so it is listed and marked rather
|
|
137
137
|
* than dropped.
|
|
138
138
|
*/
|
|
139
139
|
declared: boolean;
|
|
140
140
|
/**
|
|
141
|
-
* How many
|
|
141
|
+
* How many other manifests declare this same lab id. Above zero, the run history below is shared
|
|
142
142
|
* between them and cannot be attributed to one file — worth saying, because it is a
|
|
143
143
|
* misconfiguration the operator almost certainly does not know about.
|
|
144
144
|
*/
|
|
@@ -169,13 +169,13 @@ export interface DeclaredLab {
|
|
|
169
169
|
* deleted — that evidence still exists on disk, so dropping those rows would make real runs
|
|
170
170
|
* unreachable from the surface that is supposed to list them.
|
|
171
171
|
*
|
|
172
|
-
*
|
|
172
|
+
* One row per manifest, not per id. The two are not the same thing: a manifest is addressed by its
|
|
173
173
|
* filename while its runs attribute to the id declared inside it, so several files can legitimately
|
|
174
174
|
* share an id. Collapsing them hides a real file; keying by id duplicates a row with no way to tell
|
|
175
175
|
* the copies apart. Both happen in practice — this repo has exactly that pair.
|
|
176
176
|
*
|
|
177
177
|
* Order puts a lab someone is working in first, then labs by how recently they ran, then declared
|
|
178
|
-
* labs that have never run (alphabetically
|
|
178
|
+
* labs that have never run (alphabetically by the displayed label, so the order on screen is the
|
|
179
179
|
* order a reader can predict), then labs known only from history.
|
|
180
180
|
*/
|
|
181
181
|
export declare function labRows(declared: readonly DeclaredLab[], entries: readonly RunIndexEntry[]): {
|
package/dist/run/projection.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// the parts most likely to be wrong are testable without a terminal.
|
|
4
4
|
//
|
|
5
5
|
// The honesty rules these encode, because they are the ones a UI is most tempted to break:
|
|
6
|
-
// - a statistic
|
|
6
|
+
// - a statistic always carries its denominator, and says when it has none;
|
|
7
7
|
// - an unknown cost is `null` (declared absent), never 0;
|
|
8
8
|
// - truncation is reported, never silent;
|
|
9
9
|
// - a participant's reported thinking is quoted, never paraphrased or summarized.
|
|
@@ -58,11 +58,11 @@ function recencyOf(entry) {
|
|
|
58
58
|
return 0;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Derive what to expect from a lab's own history. Only
|
|
61
|
+
* Derive what to expect from a lab's own history. Only finished runs count: an interrupted run's
|
|
62
62
|
* duration is the length of an accident, not of a study, and including it would quietly bias the
|
|
63
63
|
* estimate the operator uses to decide whether to press Start.
|
|
64
64
|
*
|
|
65
|
-
*
|
|
65
|
+
* The mode matters: mixing modes produces a false figure. A dry run spends nothing and
|
|
66
66
|
* takes no time, so a median over nine dry runs and one live one reports that a live run is free —
|
|
67
67
|
* next to a control that spends money. Pass the mode the figure is about; omit it only for a
|
|
68
68
|
* summary that is not attached to an action.
|
|
@@ -78,7 +78,7 @@ export function expectationFor(entries, mode) {
|
|
|
78
78
|
.map((entry) => entry.estimatedCostUsd)
|
|
79
79
|
.filter((value) => typeof value === "number" && Number.isFinite(value))
|
|
80
80
|
.sort((a, b) => a - b);
|
|
81
|
-
// A cost is unknown whether it was
|
|
81
|
+
// A cost is unknown whether it was declared absent (`null`) or never recorded at all
|
|
82
82
|
// (`undefined` — every fail-closed exit finalized with no outcome). Counting only the first
|
|
83
83
|
// reports "~$1.20 median · 3 runs" for a sample where two runs were never priced, which claims a
|
|
84
84
|
// denominator the figure does not have.
|
|
@@ -134,7 +134,7 @@ export function expectationLine(expectation) {
|
|
|
134
134
|
/**
|
|
135
135
|
* The one line a lab may say about itself, wherever it is shown.
|
|
136
136
|
*
|
|
137
|
-
* Prefers
|
|
137
|
+
* Prefers live figures: cost and duration are what someone reads before spending, and a median
|
|
138
138
|
* diluted by dry runs reports a live study as cheaper and faster than it has ever been. With no
|
|
139
139
|
* live history it reports the count and claims nothing about time or money — which is why this is
|
|
140
140
|
* shared rather than reimplemented per surface, since the two disagreeing is the whole failure.
|
|
@@ -253,13 +253,13 @@ function labNameFromPath(manifestPath) {
|
|
|
253
253
|
* deleted — that evidence still exists on disk, so dropping those rows would make real runs
|
|
254
254
|
* unreachable from the surface that is supposed to list them.
|
|
255
255
|
*
|
|
256
|
-
*
|
|
256
|
+
* One row per manifest, not per id. The two are not the same thing: a manifest is addressed by its
|
|
257
257
|
* filename while its runs attribute to the id declared inside it, so several files can legitimately
|
|
258
258
|
* share an id. Collapsing them hides a real file; keying by id duplicates a row with no way to tell
|
|
259
259
|
* the copies apart. Both happen in practice — this repo has exactly that pair.
|
|
260
260
|
*
|
|
261
261
|
* Order puts a lab someone is working in first, then labs by how recently they ran, then declared
|
|
262
|
-
* labs that have never run (alphabetically
|
|
262
|
+
* labs that have never run (alphabetically by the displayed label, so the order on screen is the
|
|
263
263
|
* order a reader can predict), then labs known only from history.
|
|
264
264
|
*/
|
|
265
265
|
export function labRows(declared, entries) {
|
|
@@ -310,7 +310,7 @@ export function labRows(declared, entries) {
|
|
|
310
310
|
.filter((lab) => !declaredIds.has(lab.labId))
|
|
311
311
|
.map((lab) => build(lab.labId, undefined, false)),
|
|
312
312
|
];
|
|
313
|
-
// Resolve each row's label
|
|
313
|
+
// Resolve each row's label before sorting, so the list is ordered by what a reader actually sees.
|
|
314
314
|
assignLabels(rows);
|
|
315
315
|
const label = (row) => row.label;
|
|
316
316
|
rows.sort((left, right) => {
|
package/dist/run/reclaim.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type E2BDesktopModule } from "../substrates/e2b/sdk.js";
|
|
2
|
+
import { type PreparedRunArtifactPaths } from "./paths.js";
|
|
2
3
|
declare const RECLAIM_RESULT_SCHEMA = "humanish.reclaim-result.v1";
|
|
3
4
|
export declare const RECLAIM_RECEIPT_ARTIFACT = "reclaim-receipt.json";
|
|
4
5
|
interface ReclaimOutcome {
|
|
@@ -31,6 +32,11 @@ export interface ReclaimHooks {
|
|
|
31
32
|
requestTimeoutMs?: number;
|
|
32
33
|
}
|
|
33
34
|
export declare function reclaimRunSandboxes(cwd: string, runInput: string, hooks?: ReclaimHooks): Promise<ReclaimResult>;
|
|
35
|
+
/**
|
|
36
|
+
* Reclaim the run whose directory the caller already holds. Nothing is resolved, so an id that is
|
|
37
|
+
* also an alias (a run named `latest`) cannot reach another run's receipts.
|
|
38
|
+
*/
|
|
39
|
+
export declare function reclaimPinnedRunSandboxes(cwd: string, runPaths: PreparedRunArtifactPaths, hooks?: ReclaimHooks): Promise<ReclaimResult>;
|
|
34
40
|
/**
|
|
35
41
|
* Kill the sandboxes left by interrupted `humanish lab preflight` probes. A probe journals under
|
|
36
42
|
* .humanish/preflight/<probe-id>/ and removes the journal after a confirmed kill, so what is left
|
package/dist/run/reclaim.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `humanish reclaim`: kill an interrupted run's sandboxes by the
|
|
1
|
+
// `humanish reclaim`: kill an interrupted run's sandboxes by the exact ids the run journaled at
|
|
2
2
|
// create time (sandbox-receipts.ndjson), and report what happened to each. It reads one file inside
|
|
3
3
|
// the managed run dir, kills by id, and never lists the account: an account-wide operation once
|
|
4
4
|
// destroyed unrelated infrastructure. Without it, orphaned sandboxes run until the server-side
|
|
@@ -13,7 +13,17 @@ import { redactText, toErrorMessage } from "../evidence/redaction.js";
|
|
|
13
13
|
import { runIdOf } from "./paths.js";
|
|
14
14
|
const RECLAIM_RESULT_SCHEMA = "humanish.reclaim-result.v1";
|
|
15
15
|
export const RECLAIM_RECEIPT_ARTIFACT = "reclaim-receipt.json";
|
|
16
|
-
export
|
|
16
|
+
export function reclaimRunSandboxes(cwd, runInput, hooks = {}) {
|
|
17
|
+
return reclaimRun(cwd, runInput, () => resolveRunPath(cwd, runInput), hooks);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Reclaim the run whose directory the caller already holds. Nothing is resolved, so an id that is
|
|
21
|
+
* also an alias (a run named `latest`) cannot reach another run's receipts.
|
|
22
|
+
*/
|
|
23
|
+
export function reclaimPinnedRunSandboxes(cwd, runPaths, hooks = {}) {
|
|
24
|
+
return reclaimRun(cwd, runIdOf(runPaths), () => Promise.resolve(runPaths), hooks);
|
|
25
|
+
}
|
|
26
|
+
async function reclaimRun(cwd, runInput, locate, hooks) {
|
|
17
27
|
const warnings = [];
|
|
18
28
|
const base = {
|
|
19
29
|
schema: RECLAIM_RESULT_SCHEMA,
|
|
@@ -25,7 +35,7 @@ export async function reclaimRunSandboxes(cwd, runInput, hooks = {}) {
|
|
|
25
35
|
};
|
|
26
36
|
if (e2bDebugMode())
|
|
27
37
|
return { ...base, ok: false, error: E2B_DEBUG_REFUSAL };
|
|
28
|
-
const runPaths = await
|
|
38
|
+
const runPaths = await locate();
|
|
29
39
|
if (!runPaths) {
|
|
30
40
|
return {
|
|
31
41
|
...base,
|
package/dist/run/results.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface RunResult {
|
|
|
30
30
|
observer?: ObserverResult;
|
|
31
31
|
warnings: string[];
|
|
32
32
|
error?: {
|
|
33
|
-
code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_ANALYSIS_UNSUPPORTED" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "
|
|
33
|
+
code: "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_ANALYSIS_UNSUPPORTED" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_LAB_COMMS_UNSUPPORTED" | "HUMANISH_LIVE_RUN_UNIMPLEMENTED" | "HUMANISH_INVALID_CWD" | "HUMANISH_RUN_ID_IN_USE" | "HUMANISH_INVALID_SIM_COUNT" | "HUMANISH_INVALID_PORT" | "HUMANISH_UNSUPPORTED_RERUN_FLAGS" | "HUMANISH_WATCH_OPTION_CONFLICT" | "HUMANISH_WATCH_SAFE_NOT_APPLICABLE" | "HUMANISH_APP_URL_REMOVED" | "HUMANISH_LAB_SCORER_BAD_REF" | "HUMANISH_LAB_SCORER_NOT_FOUND" | "HUMANISH_LAB_SCORER_LOAD_FAILED" | "HUMANISH_LAB_SCORER_NO_HOOKS" | "HUMANISH_LAB_SCORER_UNSUPPORTED_BACKEND";
|
|
34
34
|
message: string;
|
|
35
35
|
};
|
|
36
36
|
}
|
package/dist/run/run-index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface RunIndexEntry {
|
|
|
7
7
|
liveness: RunLiveness;
|
|
8
8
|
mode?: "dry-run" | "live";
|
|
9
9
|
/**
|
|
10
|
-
* The pid that owns a run, when it recorded one. This is how a surface identifies the run
|
|
10
|
+
* The pid that owns a run, when it recorded one. This is how a surface identifies the run it just
|
|
11
11
|
* started without minting an id or guessing at a new directory: it spawned a process, and exactly
|
|
12
12
|
* one run's record carries that pid.
|
|
13
13
|
*/
|
package/dist/run/run-index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// The run index (#455 PR 2): list and classify every run in a project
|
|
1
|
+
// The run index (#455 PR 2): list and classify every run in a project without parsing bundles.
|
|
2
2
|
//
|
|
3
3
|
// The existing `listRuns` walks each run tree — screenshots included — validating symlinks and
|
|
4
4
|
// then parses each `run.json`: measured 197ms cold / 152ms warm at 25 runs. That is fine for a
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
// over SSH. This module reads the small `status.json` record each run now writes (586 bytes beside
|
|
7
7
|
// a 92KB bundle) and caches per-run entries keyed on the stat of the file each was derived from.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// Honesty rules, unchanged from the record itself:
|
|
10
10
|
// - `run.json` is the evidence-of-record. Every field here is a projection for listing and
|
|
11
11
|
// classification; nothing here is a claim about what a participant did.
|
|
12
|
-
// - A run with no status record is
|
|
12
|
+
// - A run with no status record is not assumed finished. It is classified from what is on disk:
|
|
13
13
|
// a bundle means finished, receipts without a bundle mean interrupted. That is the honest
|
|
14
14
|
// reading of a run whose process died — and, before this contract existed, of every run.
|
|
15
15
|
// - One unreadable run directory degrades that run, never the listing.
|
|
@@ -97,7 +97,7 @@ function usableStatusRecord(raw, runId) {
|
|
|
97
97
|
return isRunStatusRecord(raw) && raw.runId === runId;
|
|
98
98
|
}
|
|
99
99
|
/**
|
|
100
|
-
* The bundle-only reading, for a run with no usable status record. A bundle on disk
|
|
100
|
+
* The bundle-only reading, for a run with no usable status record. A bundle on disk usually means
|
|
101
101
|
* the run reached its final write. But a live run now flushes an IN-PROGRESS bundle as it goes (so
|
|
102
102
|
* anything asking what a participant is doing has something to read), and that bundle marks its
|
|
103
103
|
* simulations `running`. With no status record there is no freshness to judge, and the honest
|
|
@@ -169,15 +169,15 @@ export async function readRunIndex(cwdInput, options = {}) {
|
|
|
169
169
|
if (statusKey !== null) {
|
|
170
170
|
const cached = cache?.get(runId, statusKey);
|
|
171
171
|
if (cached !== undefined) {
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
|
|
172
|
+
// A running record's liveness is time-dependent, so it is recomputed even on a cache hit:
|
|
173
|
+
// an unchanged record can still have gone stale. An ended record (finished or
|
|
174
|
+
// interrupted, both with completedAt) keeps the liveness it was cached with.
|
|
175
|
+
runs.push(cached.derivedFrom === "status" &&
|
|
176
|
+
cached.updatedAt !== undefined &&
|
|
177
|
+
cached.completedAt === undefined
|
|
175
178
|
? {
|
|
176
179
|
...cached,
|
|
177
|
-
liveness: classifyRunStatus({
|
|
178
|
-
state: cached.completedAt === undefined ? "running" : "finished",
|
|
179
|
-
updatedAt: cached.updatedAt,
|
|
180
|
-
}, nowMs),
|
|
180
|
+
liveness: classifyRunStatus({ state: "running", updatedAt: cached.updatedAt }, nowMs),
|
|
181
181
|
}
|
|
182
182
|
: cached);
|
|
183
183
|
continue;
|
package/dist/run/run.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ interface StartRunOptions {
|
|
|
13
13
|
lab?: RunLabProvenance | undefined;
|
|
14
14
|
/** review.md for the published bundle. */
|
|
15
15
|
renderReview: (bundle: RunBundle) => string;
|
|
16
|
-
/** Used by `FinishedRun.renderObserver`; `render` is the
|
|
16
|
+
/** Used by `FinishedRun.renderObserver`; `render` is the `LabDeps.renderObserver` seam. */
|
|
17
17
|
observer?: {
|
|
18
18
|
open: boolean;
|
|
19
19
|
render?: typeof renderObserver | undefined;
|
|
@@ -25,7 +25,9 @@ interface Run {
|
|
|
25
25
|
readonly runId: string;
|
|
26
26
|
readonly createdAt: string;
|
|
27
27
|
readonly mode: "dry-run" | "live";
|
|
28
|
-
/**
|
|
28
|
+
/** The manifest the run came from (#455); bundleHead copies it into the bundle. */
|
|
29
|
+
readonly lab?: RunLabProvenance;
|
|
30
|
+
/** Routes write their evidence files through these and hand them to participants. */
|
|
29
31
|
readonly paths: PreparedRunArtifactPaths;
|
|
30
32
|
/**
|
|
31
33
|
* Publish an in-progress bundle: run.json, review.json, review.md, events.ndjson and
|
package/dist/run/run.js
CHANGED
|
@@ -7,6 +7,7 @@ import { renderObserver } from "../observer/render.js";
|
|
|
7
7
|
import { RUN_BUNDLE_FILE, PUBLIC_TARGET_CWD } from "./bundle.js";
|
|
8
8
|
import {} from "./results.js";
|
|
9
9
|
import { createRunArtifactPaths, validatePreparedRunArtifactPaths, } from "./paths.js";
|
|
10
|
+
import { registerActiveRun } from "./active-runs.js";
|
|
10
11
|
import { writeContainedOutputFile, writePreparedRunLatestPointer } from "./contained-output.js";
|
|
11
12
|
import { beginRunStatus, runStatusOutcome, } from "./status.js";
|
|
12
13
|
/** An entry point called in a state that does not admit it. */
|
|
@@ -66,6 +67,7 @@ export async function runScope(fn) {
|
|
|
66
67
|
let closed = false;
|
|
67
68
|
let started = false;
|
|
68
69
|
let status;
|
|
70
|
+
let unregister;
|
|
69
71
|
let finished;
|
|
70
72
|
const admitted = new Set();
|
|
71
73
|
const admit = (operation) => {
|
|
@@ -86,11 +88,11 @@ export async function runScope(fn) {
|
|
|
86
88
|
const created = await createRunArtifactPaths(options.cwd, runId);
|
|
87
89
|
if (!created.ok)
|
|
88
90
|
return created;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
91
|
+
// beginRunStatus reads only the mode and the lab provenance from the run's options.
|
|
92
|
+
status = beginRunStatus(created.paths, { ...options, runId });
|
|
93
|
+
// Registered before the first write lands: a signal while it is still settling reaches
|
|
94
|
+
// the handle, whose interrupt queues behind that write.
|
|
95
|
+
unregister = registerActiveRun({ cwd: options.cwd, runId, paths: created.paths, status });
|
|
94
96
|
await status.started;
|
|
95
97
|
return { ok: true, run: openRun(options, runId, created.paths, status) };
|
|
96
98
|
})());
|
|
@@ -154,6 +156,7 @@ export async function runScope(fn) {
|
|
|
154
156
|
runId,
|
|
155
157
|
createdAt,
|
|
156
158
|
mode: options.mode,
|
|
159
|
+
...(options.lab === undefined ? {} : { lab: options.lab }),
|
|
157
160
|
paths,
|
|
158
161
|
writeSnapshot(bundle) {
|
|
159
162
|
if (closed)
|
|
@@ -193,6 +196,7 @@ export async function runScope(fn) {
|
|
|
193
196
|
finally {
|
|
194
197
|
if (finished === undefined)
|
|
195
198
|
await status?.finish();
|
|
199
|
+
unregister?.();
|
|
196
200
|
}
|
|
197
201
|
}
|
|
198
202
|
return { result: outcome.result, finished };
|
|
@@ -4,7 +4,7 @@ export declare const SANDBOX_RECEIPTS_ARTIFACT = "sandbox-receipts.ndjson";
|
|
|
4
4
|
export type SandboxProviderId = "e2b";
|
|
5
5
|
export interface SandboxReceipt {
|
|
6
6
|
at: string;
|
|
7
|
-
/** The
|
|
7
|
+
/** The participant or subject label the sandbox belongs to (public-safe token). */
|
|
8
8
|
laneId: string;
|
|
9
9
|
/** Who allocated the sandbox. Receipts written before this field existed have none. */
|
|
10
10
|
provider?: SandboxProviderId;
|
|
@@ -21,10 +21,10 @@ export interface ParsedSandboxReceipt extends Omit<SandboxReceipt, "provider"> {
|
|
|
21
21
|
provider: string;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* Append one receipt. Best-effort
|
|
25
|
-
* receipt write must never fail the
|
|
24
|
+
* Append one receipt. Best-effort by design: the receipt exists to protect the run, so a failed
|
|
25
|
+
* receipt write must never fail the participant — the only cost of a miss is that `reclaim` cannot see
|
|
26
26
|
* this id and the TTL backstop covers it instead. Containment is the same prepare step every
|
|
27
|
-
* artifact write uses; append (not atomic-replace) keeps racing
|
|
27
|
+
* artifact write uses; append (not atomic-replace) keeps racing participants' receipts intact.
|
|
28
28
|
*/
|
|
29
29
|
export declare function appendSandboxReceipt(root: PreparedOutputRoot, receipt: SandboxReceipt): Promise<void>;
|
|
30
30
|
/** Parse a receipts file leniently: a torn final line (crash mid-append) drops, valid lines keep. */
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// Every created sandbox id is journaled to the run dir the moment create returns, before any work
|
|
2
|
-
// happens in it. The
|
|
2
|
+
// happens in it. The participant loop lives in the caller's local process, so a sleeping laptop, crash or
|
|
3
3
|
// kill loses every in-memory id; this append-only file keeps them for `humanish reclaim`.
|
|
4
4
|
import { appendFile } from "node:fs/promises";
|
|
5
5
|
import { prepareContainedOutputFile } from "./contained-output.js";
|
|
6
6
|
export const SANDBOX_RECEIPTS_ARTIFACT = "sandbox-receipts.ndjson";
|
|
7
7
|
/**
|
|
8
|
-
* Append one receipt. Best-effort
|
|
9
|
-
* receipt write must never fail the
|
|
8
|
+
* Append one receipt. Best-effort by design: the receipt exists to protect the run, so a failed
|
|
9
|
+
* receipt write must never fail the participant — the only cost of a miss is that `reclaim` cannot see
|
|
10
10
|
* this id and the TTL backstop covers it instead. Containment is the same prepare step every
|
|
11
|
-
* artifact write uses; append (not atomic-replace) keeps racing
|
|
11
|
+
* artifact write uses; append (not atomic-replace) keeps racing participants' receipts intact.
|
|
12
12
|
*/
|
|
13
13
|
export async function appendSandboxReceipt(root, receipt) {
|
|
14
14
|
try {
|
|
@@ -1,58 +1,58 @@
|
|
|
1
1
|
import type { ParticipantIds } from "./participant-records.js";
|
|
2
2
|
export declare const SHARED_WORLD_SCHEMA = "humanish.shared-world.v1";
|
|
3
|
-
/** The
|
|
4
|
-
* seed-recipe digest + the provisioned env
|
|
3
|
+
/** The shared service-plane provenance for a shared-world run (#164): single commit + a
|
|
4
|
+
* seed-recipe digest + the provisioned env names (never values). */
|
|
5
5
|
export interface SharedWorldPlane {
|
|
6
6
|
/** The cloned commit SHA of the shared plane (when the clone resolved one). */
|
|
7
7
|
commit?: string;
|
|
8
|
-
/** sha256-16 over the ordered seed-step command digests
|
|
8
|
+
/** sha256-16 over the ordered seed-step command digests: the seeded-state recipe identity
|
|
9
9
|
* (not the runtime state). Pins "same seed recipe" across bundles. */
|
|
10
10
|
seedDigest: string;
|
|
11
|
-
/** Declared env
|
|
11
|
+
/** Declared env names provisioned for the shared plane (values never surface). */
|
|
12
12
|
envNames: string[];
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
15
|
-
* (the first-class provisioned-subject target every actor drove
|
|
14
|
+
* Concurrent route only (#164 phase 2): sha256-16 of the harness-minted `getHost` URL's origin
|
|
15
|
+
* (the first-class provisioned-subject target every actor drove, per invariant 2). A digest replaces the
|
|
16
16
|
* raw URL: a getHost URL embeds the (live) sandbox id and matches the publish-safety e2b-URL
|
|
17
17
|
* redaction, so — like the stream URL and like sandbox ids — it never lands raw in a published
|
|
18
18
|
* bundle (the raw tokenless URL is surfaced only on the ephemeral lab result). The orchestrator
|
|
19
|
-
* confirms the URL is
|
|
19
|
+
* confirms the URL is tokenless (no authKey, per invariant 1) before digesting. verify proves every
|
|
20
20
|
* actor drove this host by digest equality. Absent on the sequential route.
|
|
21
21
|
*/
|
|
22
22
|
hostDigest?: string;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
* internet-reachable getHost URL is synthetic seeded data
|
|
26
|
-
* provenance gate
|
|
24
|
+
* Concurrent route only: the author's required attestation that the subject behind the
|
|
25
|
+
* internet-reachable getHost URL is synthetic seeded data. This is author-trust + a
|
|
26
|
+
* provenance gate; it does not guarantee the data is synthetic. Verify fails closed if absent on the concurrent route.
|
|
27
27
|
*
|
|
28
|
-
*
|
|
29
|
-
* harness neither provisioned nor exposed would be
|
|
28
|
+
* Forbidden on the external-public plane class: claiming synthetic on a real public site the
|
|
29
|
+
* harness neither provisioned nor exposed would be false (verify asserts it is absent there).
|
|
30
30
|
*/
|
|
31
31
|
exposure?: "synthetic";
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* seats actually reached
|
|
37
|
-
* (that seat's CDP-observed final URL origin) equals it
|
|
33
|
+
* External-public plane class only (#164 phase 2): sha256-16 of the observed origin the seats
|
|
34
|
+
* converged on. It is the counterpart of hostDigest with a weaker, disclosed claim: the harness only
|
|
35
|
+
* observes that each seat reached this origin and never minted it. It is derived from what the
|
|
36
|
+
* seats actually reached; the declared appUrl does not feed it. verify proves every laneWindow.routeHostDigest
|
|
37
|
+
* (that seat's CDP-observed final URL origin) equals it, which shows inter-seat convergence on one observed
|
|
38
38
|
* origin, not harness control of the plane. A digest, not the raw origin (kept consistent with
|
|
39
39
|
* hostDigest hygiene). Absent on getHost.
|
|
40
40
|
*/
|
|
41
41
|
publicOriginDigest?: string;
|
|
42
42
|
/**
|
|
43
43
|
* EXTERNAL-PUBLIC plane class only: sha256-16 of the operator-DECLARED origin (from subject.appUrl),
|
|
44
|
-
* recorded for reference/evidence
|
|
45
|
-
* cross-origin redirect (apex->www, http->https) makes the
|
|
46
|
-
* one, which is expected. Operator
|
|
47
|
-
* + the declared appUrl
|
|
44
|
+
* recorded for reference/evidence only. It is never asserted equal to publicOriginDigest: a normal
|
|
45
|
+
* cross-origin redirect (apex->www, http->https) makes the observed origin differ from the declared
|
|
46
|
+
* one, which is expected. Operator ownership rests on the subject.publicTarget.authorized attestation
|
|
47
|
+
* + the declared appUrl; digest equality plays no part. Only the digest is stored. Absent on getHost.
|
|
48
48
|
*/
|
|
49
49
|
declaredOriginDigest?: string;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
*
|
|
53
|
-
* shared plane.
|
|
54
|
-
* `laneWindows` and `stateSeries` are
|
|
55
|
-
* field
|
|
52
|
+
* Concurrent shape (#164 phase 2): one actor's harness-clocked activity window against the one
|
|
53
|
+
* shared plane. Overlapping windows mechanically prove ≥2 personas were active simultaneously.
|
|
54
|
+
* `laneWindows` and `stateSeries` are independent series. There is deliberately no per-delta→actor
|
|
55
|
+
* field, because under concurrency the evidence cannot say which actor caused a state change.
|
|
56
56
|
*/
|
|
57
57
|
export interface SharedWorldParticipantWindow {
|
|
58
58
|
roleId: string;
|
|
@@ -63,13 +63,13 @@ export interface SharedWorldParticipantWindow {
|
|
|
63
63
|
simId: string;
|
|
64
64
|
/** Resolves to a real RunStream (the actor's trace) in this bundle. */
|
|
65
65
|
streamId: string;
|
|
66
|
-
/** ms on the
|
|
66
|
+
/** ms on the one harness clock: the wrapped [start,end] the orchestrator measured. */
|
|
67
67
|
startedAt: number;
|
|
68
68
|
endedAt: number;
|
|
69
69
|
/** The actor's terminal session verdict (per-persona). */
|
|
70
70
|
verdict: string;
|
|
71
|
-
/** sha256-16 of the
|
|
72
|
-
* plane.hostDigest
|
|
71
|
+
/** sha256-16 of the origin of the getHost seat URL this actor drove. verify confirms it equals
|
|
72
|
+
* plane.hostDigest, so the actor drove exactly the harness-minted host (invariant 2).
|
|
73
73
|
* A digest, not the raw URL (a getHost URL is not publish-safe — see SharedWorldPlane.hostDigest). */
|
|
74
74
|
routeHostDigest: string;
|
|
75
75
|
/** The shared plane's commit this actor observed (omitted when unresolved). */
|
|
@@ -77,15 +77,15 @@ export interface SharedWorldParticipantWindow {
|
|
|
77
77
|
/** The shared plane's seed-recipe digest this actor observed. */
|
|
78
78
|
seedDigest: string;
|
|
79
79
|
}
|
|
80
|
-
/**
|
|
81
|
-
* allowed-keys tripwire (SHARED_WORLD_STATESERIES_KEYS) permits
|
|
80
|
+
/** Concurrent shape: one cadence checkpoint of the shared world under load. Digest-only: the
|
|
81
|
+
* allowed-keys tripwire (SHARED_WORLD_STATESERIES_KEYS) permits only {timestamp, digest}. */
|
|
82
82
|
export interface SharedWorldStateSnapshot {
|
|
83
|
-
/** ms on the
|
|
83
|
+
/** ms on the one harness clock. */
|
|
84
84
|
timestamp: number;
|
|
85
85
|
/** sha256-16 of the (scrubbed, redacted) combined probe output at this snapshot. */
|
|
86
86
|
digest: string;
|
|
87
87
|
}
|
|
88
|
-
/**
|
|
88
|
+
/** Concurrent shape: one persona's outcome against the contended world (the "M of N" headline). */
|
|
89
89
|
export interface SharedWorldOutcome {
|
|
90
90
|
roleId: string;
|
|
91
91
|
actorType?: string;
|
|
@@ -117,7 +117,7 @@ export interface SharedWorldCheckpoint {
|
|
|
117
117
|
/** sha256-16 of the (scrubbed, redacted) combined probe output at this snapshot. */
|
|
118
118
|
digest: string;
|
|
119
119
|
/** True when this snapshot's digest differs from the previous checkpoint's — the observed
|
|
120
|
-
* state changed across the intervening turn (delta attributed to the
|
|
120
|
+
* state changed across the intervening turn (the delta is attributed to the whole turn). */
|
|
121
121
|
deltaFromPrev: boolean;
|
|
122
122
|
}
|
|
123
123
|
/** A timeline turn: one role's seat session against the shared plane. Carries the plane
|
|
@@ -150,45 +150,45 @@ interface SharedWorldSkippedTail {
|
|
|
150
150
|
estimatedTotalUsd?: number;
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
153
|
-
* The shared-world evidence block (`humanish.shared-world.v1`).
|
|
154
|
-
* `topologyMode
|
|
153
|
+
* The shared-world evidence block (`humanish.shared-world.v1`). Two variants discriminated by
|
|
154
|
+
* `topologyMode`, which is named so it does not collide with `RunBundle.mode` (dry-run|live):
|
|
155
155
|
*
|
|
156
|
-
* -
|
|
156
|
+
* - Sequential (`topologyMode: "sequential"`): `sequence` + an alternating `timeline`
|
|
157
157
|
* (cp-baseline → turn → cp → … → cp); limits `sequential-only` etc. No route writes it since
|
|
158
158
|
* 0.106.0; verify still reads it so older bundles keep verifying.
|
|
159
|
-
* -
|
|
160
|
-
* `outcomes`; limits `concurrent` etc.
|
|
159
|
+
* - Concurrent (`topologyMode: "concurrent"`, #164 phase 2): `laneWindows` + `stateSeries` +
|
|
160
|
+
* `outcomes`; limits `concurrent` etc. No `timeline`.
|
|
161
161
|
*
|
|
162
162
|
* Additive + optional on `humanish.run-bundle.v1` — absent on every non-shared-world bundle.
|
|
163
|
-
* The mandatory `attributionLimits` are verify-enforced (
|
|
163
|
+
* The mandatory `attributionLimits` are verify-enforced (fail closed on a missing required or a
|
|
164
164
|
* present forbidden limit).
|
|
165
165
|
*/
|
|
166
166
|
export interface SharedWorldEvidence {
|
|
167
167
|
schema: typeof SHARED_WORLD_SCHEMA;
|
|
168
168
|
topology: "shared-world";
|
|
169
|
-
/** The substrate discriminator
|
|
169
|
+
/** The substrate discriminator. Branched on first by sharedWorldEvidenceFindings. */
|
|
170
170
|
topologyMode: "sequential" | "concurrent";
|
|
171
171
|
/**
|
|
172
|
-
*
|
|
172
|
+
* Concurrent route only (#164 phase 2): the plane-class discriminator. Absent == the historical
|
|
173
173
|
* "provisioned-getHost" plane (a clone/local-tree subject served + getHost-exposed in-sandbox — the
|
|
174
|
-
* harness
|
|
174
|
+
* harness minted the host; synthetic-seeded attestation + authoritative in-sandbox checkpoint
|
|
175
175
|
* stateSeries). "external-public" == a real operator-owned public deployment used directly as the
|
|
176
|
-
* plane (
|
|
176
|
+
* plane (no getHost/clone/seed; the operator attests it and the harness does not control it; no authoritative
|
|
177
177
|
* shared-state proof — concurrency evidenced by temporal co-occupancy + observed lobby convergence).
|
|
178
|
-
* verify gates
|
|
178
|
+
* verify gates every getHost-specific assertion on this discriminator; existing bundles omit it and
|
|
179
179
|
* default to provisioned-getHost, byte-stable.
|
|
180
180
|
*/
|
|
181
181
|
planeClass?: "provisioned-getHost" | "external-public";
|
|
182
|
-
/** The
|
|
182
|
+
/** The declared number of role seats. */
|
|
183
183
|
roleCount: number;
|
|
184
184
|
plane: SharedWorldPlane;
|
|
185
185
|
/** The pinned, verify-enforced attribution ceiling (the set differs per topologyMode/planeClass). */
|
|
186
186
|
attributionLimits: string[];
|
|
187
187
|
/**
|
|
188
188
|
* EXTERNAL-PUBLIC plane class only (#164 phase 2, optional-but-strong): sha256-16 of the shared
|
|
189
|
-
* `/lobby/CODE`
|
|
189
|
+
* `/lobby/CODE` path every seat's CDP-observed URL converged on: the concrete "they were in one
|
|
190
190
|
* shared world" proof, observation-derived and needing no subject change. Digest-only (the raw
|
|
191
|
-
* 6-char
|
|
191
|
+
* 6-char lobby code and full URLs are runtime-only and never land). Absent when seats did not converge.
|
|
192
192
|
*/
|
|
193
193
|
lobbyConvergenceDigest?: string;
|
|
194
194
|
/** The role ids that actually took a turn, in declared order. */
|
|
@@ -6,7 +6,7 @@ export declare const MANDATORY_ATTRIBUTION_LIMITS: readonly ["sequential-only",
|
|
|
6
6
|
export declare const SHARED_WORLD_CHECKPOINT_KEYS: Set<string>;
|
|
7
7
|
export declare const SHARED_WORLD_STATESERIES_KEYS: Set<string>;
|
|
8
8
|
/**
|
|
9
|
-
* Single-plane provenance: every item shares
|
|
9
|
+
* Single-plane provenance: every item shares one (commit, seedDigest), and that pair matches
|
|
10
10
|
* sharedWorld.plane. Only the first item that diverges from the plane is reported. The shape guard
|
|
11
11
|
* has already typed both fields as strings (commit may be absent).
|
|
12
12
|
*/
|
|
@@ -18,8 +18,8 @@ export declare function planeProvenanceFindings(items: readonly Record<string, u
|
|
|
18
18
|
/** Common shape findings shared by both topologyMode branches. */
|
|
19
19
|
export declare function sharedWorldCommonFindings(bundle: RunBundle, sw: SharedWorldEvidence): string[];
|
|
20
20
|
/**
|
|
21
|
-
* Tolerant
|
|
22
|
-
* types
|
|
21
|
+
* Tolerant shape guard for the shared-world evidence block (#164). Validates required fields +
|
|
22
|
+
* types and tolerates extra keys (additive): the strict value-shape/timeline checks are
|
|
23
23
|
* sharedWorldEvidenceFindings' job (an injected value-shaped checkpoint field must pass the shape
|
|
24
24
|
* guard so verify can catch it fail-closed, not silently bounce off isRunBundle).
|
|
25
25
|
*/
|