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
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
// The
|
|
2
|
-
// mutable service plane
|
|
1
|
+
// The concurrent shared-world lab backend (#164 phase 2): N persona participants drive one shared,
|
|
2
|
+
// mutable service plane at the same time. A recomposition of shipped
|
|
3
3
|
// pieces + the getHost wrapper:
|
|
4
4
|
//
|
|
5
|
-
// -
|
|
5
|
+
// - One subject sandbox: provisionCloneSubject once (clone+install+build+seed) + serve on
|
|
6
6
|
// 0.0.0.0, exposed via getHost(port) → a tokenless reachable URL (the headless service host;
|
|
7
7
|
// no GUI seat).
|
|
8
|
-
// - N
|
|
8
|
+
// - N actor desktop sandboxes: fan-out's runCuaParticipant machinery (per-participant device/persona, by-id
|
|
9
9
|
// teardown) bounded by execution.concurrency, each browser pointed at the getHost URL —
|
|
10
|
-
// driving the shared service
|
|
10
|
+
// driving the shared service at the same time. Independent: no pipeline gate, no
|
|
11
11
|
// fail-fast — one actor's failure must not block the swarm or corrupt the "M of N" outcomes.
|
|
12
12
|
// - A background prober snapshots the subject DB checkpoint digests on a cadence → a stateSeries
|
|
13
13
|
// of the shared world evolving under load.
|
|
14
|
-
// -
|
|
14
|
+
// - All N+1 sandboxes torn down by exact id in a finally, never through Sandbox.list.
|
|
15
15
|
//
|
|
16
|
-
//
|
|
17
|
-
// attributionClass: shared-world + a
|
|
18
|
-
// "concurrent"; laneWindows + stateSeries + outcomes;
|
|
16
|
+
// Attribution (enforced by verify): the bundle declares
|
|
17
|
+
// attributionClass: shared-world + a concurrent humanish.shared-world.v1 block (topologyMode
|
|
18
|
+
// "concurrent"; laneWindows + stateSeries + outcomes; no timeline) whose attributionLimits drop
|
|
19
19
|
// `sequential-only`/`no-concurrent-races` and add `concurrent`,
|
|
20
20
|
// `best-effort-causal-attribution`, `non-deterministic-shared-state`,
|
|
21
21
|
// `window-and-snapshot-granularity`, `contention-observed-not-proven-safe`,
|
|
22
|
-
// `state-change-not-isolated-to-actors`. laneWindows + stateSeries are
|
|
22
|
+
// `state-change-not-isolated-to-actors`. laneWindows + stateSeries are independent series with no
|
|
23
23
|
// per-delta→actor field — causation under concurrency is structurally inexpressible.
|
|
24
24
|
//
|
|
25
|
-
//
|
|
25
|
+
// Capability and proof: the deterministic $0 gate proves the plumbing + the honesty
|
|
26
26
|
// contract — the real mapWithConcurrency produces genuinely overlapping laneWindows (a rendezvous
|
|
27
|
-
// latch in the fake session forces two
|
|
27
|
+
// latch in the fake session forces two participant fns in-flight while the real orchestrator clock
|
|
28
28
|
// measures the windows). Every generated bundle describes only its own observations; no one run
|
|
29
29
|
// establishes scale, repeatability, or adopter-harness replacement.
|
|
30
30
|
//
|
|
31
|
-
// Synthetic
|
|
32
|
-
// synthetic
|
|
31
|
+
// Synthetic subject: a getHost URL is internet-reachable for the run, so this route is for
|
|
32
|
+
// synthetic seeded subjects only. Verify fail-closes on subject.state.provenance != "seeded" and
|
|
33
33
|
// requires the author attestation subject.exposure: synthetic. This is author-trust + a provenance
|
|
34
|
-
// gate
|
|
34
|
+
// gate; humanish cannot tell synthetic from real data, so it makes no claim about real data.
|
|
35
35
|
import path from "node:path";
|
|
36
|
+
import { missingKeys, missingSubjectEnv } from "../../lab/requirements.js";
|
|
36
37
|
import { completeAutomaticAnalysis } from "../../analysis/automatic-completion.js";
|
|
37
38
|
import { resolveAutomaticAnalysis } from "../../analysis/automatic-config.js";
|
|
38
39
|
import { scrubLiterals } from "../../evidence/redaction.js";
|
|
@@ -46,7 +47,8 @@ import { localAgentRefusal } from "../../actors/local-agent/readiness.js";
|
|
|
46
47
|
import { runProvisionedPlane } from "./provisioned.js";
|
|
47
48
|
import { concurrentLabFailure, finishConcurrentRun } from "./result.js";
|
|
48
49
|
import { prepareConcurrentRun } from "./setup.js";
|
|
49
|
-
import {
|
|
50
|
+
import { browserRouteScorer } from "../../lab/adapter-scorer-loader.js";
|
|
51
|
+
import { withLateScorer } from "../../lab/route-inputs.js";
|
|
50
52
|
import {} from "./types.js";
|
|
51
53
|
import { rosterOf } from "../../lab/parse/actors.js";
|
|
52
54
|
/** The shared-world code for each local-agent refusal, kind for kind with computer-use. */
|
|
@@ -62,12 +64,11 @@ const LOCAL_AGENT_REFUSAL_CODES = {
|
|
|
62
64
|
* run and its analysis.
|
|
63
65
|
*/
|
|
64
66
|
export async function runConcurrentSharedWorld(options) {
|
|
65
|
-
const { config, dryRun,
|
|
67
|
+
const { config, dryRun, ...input } = options;
|
|
66
68
|
// planSharedWorldLab makes every configuration refusal, in the order this route always has.
|
|
67
69
|
const planned = planSharedWorldLab(config, {
|
|
68
70
|
dryRun,
|
|
69
|
-
|
|
70
|
-
hooks: input.hooks ?? {},
|
|
71
|
+
hasRunSession: input.deps?.runSession !== undefined,
|
|
71
72
|
});
|
|
72
73
|
if (planned.ok)
|
|
73
74
|
return runSharedWorldPlan(planned.plan, input, config);
|
|
@@ -90,7 +91,7 @@ export function sharedWorldLabRefusal(options, refusal) {
|
|
|
90
91
|
});
|
|
91
92
|
// A refusal starts no run, so a declared or default analysis is recorded as skipped.
|
|
92
93
|
const analysis = resolveAutomaticAnalysis(config.review?.analysis);
|
|
93
|
-
return completeAutomaticAnalysis(fail(refusal.code, refusal.message, refusal.actor), undefined, analysis.ok ? analysis.config : undefined, options
|
|
94
|
+
return completeAutomaticAnalysis(fail(refusal.code, refusal.message, refusal.actor), undefined, analysis.ok ? analysis.config : undefined, options, { trigger: config.review?.analysis === undefined ? "default" : "explicit" });
|
|
94
95
|
}
|
|
95
96
|
/**
|
|
96
97
|
* runLab's step for a shared-world plan. It runs a live plan's local checks (the keys, a local
|
|
@@ -103,11 +104,11 @@ export async function admitSharedWorldPlan(plan, input, config) {
|
|
|
103
104
|
return { ok: false, outcome: sharedWorldOutcome(refused) };
|
|
104
105
|
return {
|
|
105
106
|
ok: true,
|
|
106
|
-
run: async (scorer) => sharedWorldOutcome(await runAdmittedSharedWorldRun(plan,
|
|
107
|
+
run: async (scorer) => sharedWorldOutcome(await runAdmittedSharedWorldRun(plan, withLateScorer(input, scorer, browserRouteScorer), config)),
|
|
107
108
|
};
|
|
108
109
|
}
|
|
109
110
|
function sharedWorldOutcome(result) {
|
|
110
|
-
return { route: "shared-world",
|
|
111
|
+
return { route: "shared-world", result };
|
|
111
112
|
}
|
|
112
113
|
/** Run a shared-world plan: its local checks, then the run. */
|
|
113
114
|
export async function runSharedWorldPlan(plan, input, config) {
|
|
@@ -122,18 +123,13 @@ export async function runSharedWorldPlan(plan, input, config) {
|
|
|
122
123
|
async function admitSharedWorldRun(plan, input) {
|
|
123
124
|
if (plan.dryRun)
|
|
124
125
|
return undefined;
|
|
125
|
-
const env = input.
|
|
126
|
-
const subjectEnvNames = plan.plane.kind === "provisioned" ? plan.plane.subject.env : [];
|
|
126
|
+
const env = input.env ?? process.env;
|
|
127
127
|
const fail = (code, message) => completeSharedWorldAnalysis(plan, input, sharedWorldFailure(plan, input)(code, message, sharedWorldDescriptorOf(plan.actor).id), undefined);
|
|
128
|
-
// OPENAI_API_KEY
|
|
129
|
-
// reader; a local-agent brain's seats run on the operator's signed-in agent instead.
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
...(env.E2B_API_KEY?.trim() ? [] : ["E2B_API_KEY"]),
|
|
134
|
-
];
|
|
135
|
-
if (missingKeys.length > 0) {
|
|
136
|
-
return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING", `Live concurrent shared-world labs need ${missingKeys.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missingKeys, env)}`);
|
|
128
|
+
// The plan lists OPENAI_API_KEY for an openai brain's seats and the external-public plane's
|
|
129
|
+
// lobby-code reader; a local-agent brain's seats run on the operator's signed-in agent instead.
|
|
130
|
+
const missing = missingKeys(plan.requirements, env);
|
|
131
|
+
if (missing.length > 0) {
|
|
132
|
+
return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING", `Live concurrent shared-world labs need ${missing.join(" and ")} in the environment (values are never persisted). ${describeMissingKeys(missing, env)}`);
|
|
137
133
|
}
|
|
138
134
|
if (plan.brain.kind === "local-agent") {
|
|
139
135
|
// A missing or signed-out agent found after the seats' desktops are paid for is the same
|
|
@@ -142,9 +138,9 @@ async function admitSharedWorldRun(plan, input) {
|
|
|
142
138
|
if (refusal)
|
|
143
139
|
return fail(LOCAL_AGENT_REFUSAL_CODES[refusal.kind], refusal.message);
|
|
144
140
|
}
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING", `subject.env declares ${
|
|
141
|
+
const unsetSubjectEnv = missingSubjectEnv(plan.requirements, env);
|
|
142
|
+
if (unsetSubjectEnv.length > 0) {
|
|
143
|
+
return fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING", `subject.env declares ${unsetSubjectEnv.join(", ")} but the environment does not provide ${unsetSubjectEnv.length === 1 ? "it" : "them"} (pass via --env-file; values are never persisted).`);
|
|
148
144
|
}
|
|
149
145
|
return undefined;
|
|
150
146
|
}
|
|
@@ -160,7 +156,7 @@ function runAdmittedSharedWorldRun(plan, input, config) {
|
|
|
160
156
|
});
|
|
161
157
|
}
|
|
162
158
|
function completeSharedWorldAnalysis(plan, input, result, finished) {
|
|
163
|
-
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input
|
|
159
|
+
return completeAutomaticAnalysis(result, finished, plan.analysis?.config, input, {
|
|
164
160
|
...(plan.analysis === undefined ? {} : { trigger: plan.analysis.trigger }),
|
|
165
161
|
preferLargerOutput: plan.analysis?.preferLargerOutput === true,
|
|
166
162
|
});
|
|
@@ -180,8 +176,8 @@ function sharedWorldFailure(plan, input) {
|
|
|
180
176
|
async function runPlanInScope(plan, input, config, scope) {
|
|
181
177
|
const { dryRun } = plan;
|
|
182
178
|
const requestedCwd = path.resolve(input.cwd);
|
|
183
|
-
const
|
|
184
|
-
const env =
|
|
179
|
+
const deps = input.deps ?? {};
|
|
180
|
+
const env = input.env ?? process.env;
|
|
185
181
|
const fail = sharedWorldFailure(plan, input);
|
|
186
182
|
const descriptor = sharedWorldDescriptorOf(plan.actor);
|
|
187
183
|
const planeClass = plan.plane.kind === "external-public" ? "external-public" : "provisioned-getHost";
|
|
@@ -194,7 +190,7 @@ async function runPlanInScope(plan, input, config, scope) {
|
|
|
194
190
|
const subjectRepo = plan.residual.subject.repos?.[0] ?? "";
|
|
195
191
|
const subjectEnvNames = [...(subject?.env ?? [])];
|
|
196
192
|
const checkpoints = [...(subject?.state.checkpoint ?? [])];
|
|
197
|
-
const runSession =
|
|
193
|
+
const runSession = deps.runSession ?? descriptor.runSession;
|
|
198
194
|
const openaiApiKey = env.OPENAI_API_KEY?.trim() ?? "";
|
|
199
195
|
const e2bApiKey = env.E2B_API_KEY?.trim() ?? "";
|
|
200
196
|
const knownSecretValues = [
|
|
@@ -212,7 +208,7 @@ async function runPlanInScope(plan, input, config, scope) {
|
|
|
212
208
|
input,
|
|
213
209
|
config,
|
|
214
210
|
requestedCwd,
|
|
215
|
-
|
|
211
|
+
deps,
|
|
216
212
|
env,
|
|
217
213
|
descriptor,
|
|
218
214
|
planeClass,
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
2
2
|
import type { LabConfig, LabSubjectServe, LabSubjectStateCheckpoint } from "../../lab/types.js";
|
|
3
3
|
import type { RunScope } from "../../run/run.js";
|
|
4
|
-
import type { ConcurrentSharedWorldLabErrorCode, ConcurrentSharedWorldLabResult, ConcurrentSharedWorldPlaneClass, FinishFacts, LiveParticipants, PlaneContext, PlaneResults, PlaneSelection,
|
|
4
|
+
import type { ConcurrentSharedWorldLabErrorCode, ConcurrentSharedWorldLabResult, ConcurrentSharedWorldPlaneClass, FinishFacts, LiveParticipants, PlaneContext, PlaneResults, PlaneSelection, SharedWorldRunInput } from "./types.js";
|
|
5
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
5
6
|
import type { SharedWorldPlan } from "../../lab/plan-types.js";
|
|
6
7
|
/** What validation derived from the lab, which setup reads. */
|
|
7
8
|
interface AdmittedLab {
|
|
8
9
|
plan: SharedWorldPlan;
|
|
9
10
|
input: SharedWorldRunInput;
|
|
10
|
-
/** Read
|
|
11
|
-
*
|
|
11
|
+
/** Read for the subject's serve URL, which each seat's subject names. Seats, their count and
|
|
12
|
+
* their host and entry come from the plan's participants. */
|
|
12
13
|
config: LabConfig;
|
|
13
14
|
requestedCwd: string;
|
|
14
|
-
|
|
15
|
+
deps: LabDeps;
|
|
15
16
|
env: Record<string, string | undefined>;
|
|
16
17
|
descriptor: CuaActorDescriptor;
|
|
17
18
|
planeClass: ConcurrentSharedWorldPlaneClass;
|
|
@@ -10,7 +10,7 @@ import { prepareEmailReceiving, prepareExternalComms, receivingSourceOf, subject
|
|
|
10
10
|
import { declaredOriginDigestOf } from "./external-public.js";
|
|
11
11
|
import { packSubjectTree } from "./provisioned.js";
|
|
12
12
|
import { emptyPlaneResults } from "./result.js";
|
|
13
|
-
import { buildParticipantSpecs, defaultSessionTimeoutMs } from "./
|
|
13
|
+
import { buildParticipantSpecs, defaultSessionTimeoutMs } from "./participant-specs.js";
|
|
14
14
|
import { planeStateOf } from "./plan.js";
|
|
15
15
|
import path from "node:path";
|
|
16
16
|
import { e2bRequestTimeoutMs } from "../../substrates/e2b/lifetime.js";
|
|
@@ -49,7 +49,7 @@ async function bindPhysicalProject(requestedCwd) {
|
|
|
49
49
|
.physicalPath;
|
|
50
50
|
}
|
|
51
51
|
function startConcurrentRun(lab, cwd, scope) {
|
|
52
|
-
const { plan, input,
|
|
52
|
+
const { plan, input, deps } = lab;
|
|
53
53
|
return scope.startRun({
|
|
54
54
|
cwd,
|
|
55
55
|
runId: input.runId,
|
|
@@ -57,7 +57,7 @@ function startConcurrentRun(lab, cwd, scope) {
|
|
|
57
57
|
mode: plan.dryRun ? "dry-run" : "live",
|
|
58
58
|
lab: plan.lab,
|
|
59
59
|
renderReview: renderConcurrentReviewMarkdown,
|
|
60
|
-
observer: { open: input.open === true, render:
|
|
60
|
+
observer: { open: input.open === true, render: deps.renderObserver },
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
/**
|
|
@@ -65,7 +65,7 @@ function startConcurrentRun(lab, cwd, scope) {
|
|
|
65
65
|
* specs, comms, the packed tree and email receiving. Returns the refusal when one of them fails.
|
|
66
66
|
*/
|
|
67
67
|
export async function prepareConcurrentRun(lab, scope) {
|
|
68
|
-
const { plan, input, config, requestedCwd,
|
|
68
|
+
const { plan, input, config, requestedCwd, deps, env, descriptor, planeClass, fail } = lab;
|
|
69
69
|
const { runBudget, runSession, localTreeRoute, subjectEnvNames, publicRepo } = lab;
|
|
70
70
|
const { openaiApiKey, e2bApiKey, knownSecretValues, scrubKnownValues } = lab;
|
|
71
71
|
const { dryRun, concurrency } = plan;
|
|
@@ -73,17 +73,14 @@ export async function prepareConcurrentRun(lab, scope) {
|
|
|
73
73
|
const warnings = [];
|
|
74
74
|
// The comms catch and the packed tree are checked before the run starts, so a refusal leaves
|
|
75
75
|
// no run directory. Neither spends: the probe is one request and packing runs on the host.
|
|
76
|
-
const externalComms = await prepareExternalComms(plan.residual, planeClass, dryRun, warnings);
|
|
76
|
+
const externalComms = await prepareExternalComms(plan.residual, planeClass, dryRun, warnings, env);
|
|
77
77
|
if (!externalComms.ok) {
|
|
78
|
-
return {
|
|
79
|
-
ok: false,
|
|
80
|
-
result: fail("HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE", externalComms.message),
|
|
81
|
-
};
|
|
78
|
+
return { ok: false, result: fail(externalComms.code, externalComms.message) };
|
|
82
79
|
}
|
|
83
80
|
// Pack the working tree once per run, on the host, before any sandbox exists: a packing
|
|
84
81
|
// failure fails the run closed without sandbox cost. Dry-run packs nothing.
|
|
85
82
|
const packed = localTreeRoute && !dryRun
|
|
86
|
-
? await packSubjectTree(cwd, plan.residual,
|
|
83
|
+
? await packSubjectTree(cwd, plan.residual, deps, scrubKnownValues)
|
|
87
84
|
: { ok: true, archive: undefined, buffer: undefined };
|
|
88
85
|
if (!packed.ok) {
|
|
89
86
|
return {
|
|
@@ -102,9 +99,9 @@ export async function prepareConcurrentRun(lab, scope) {
|
|
|
102
99
|
const timeoutMs = plan.sessionTimeoutMs ?? defaultSessionTimeoutMs(plan);
|
|
103
100
|
const requestTimeoutMs = e2bRequestTimeoutMs(env);
|
|
104
101
|
const redactScreenshots = plan.residual.policies?.redactScreenshots === true;
|
|
105
|
-
const timers =
|
|
106
|
-
const now =
|
|
107
|
-
const proberCadenceMs =
|
|
102
|
+
const timers = deps.detachedTimers ?? {};
|
|
103
|
+
const now = deps.now ?? Date.now;
|
|
104
|
+
const proberCadenceMs = deps.proberCadenceMs ?? DEFAULT_PROBER_CADENCE_MS;
|
|
108
105
|
const seedDigest = seedRecipeDigest(planeStateOf(plan));
|
|
109
106
|
const source = await buildRunSource({
|
|
110
107
|
capturedAt: createdAt,
|
|
@@ -147,7 +144,7 @@ export async function prepareConcurrentRun(lab, scope) {
|
|
|
147
144
|
input,
|
|
148
145
|
config,
|
|
149
146
|
descriptor,
|
|
150
|
-
|
|
147
|
+
deps,
|
|
151
148
|
env,
|
|
152
149
|
concurrency,
|
|
153
150
|
runBudget,
|
|
@@ -155,6 +152,7 @@ export async function prepareConcurrentRun(lab, scope) {
|
|
|
155
152
|
openaiApiKey,
|
|
156
153
|
e2bApiKey,
|
|
157
154
|
scrubKnownValues,
|
|
155
|
+
knownSecretValues,
|
|
158
156
|
cwd,
|
|
159
157
|
run,
|
|
160
158
|
runId,
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
+
import type { LabDeps } from "../../lab/lab-deps.js";
|
|
2
|
+
import type { LabEvent } from "../../lab/run-lab-events.js";
|
|
3
|
+
import type { RunLabHomes } from "../../lab/run-lab-homes.js";
|
|
1
4
|
import type { SharedWorldJudgment } from "../../run/judge.js";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type { BrowserLabAdapterHooks } from "../../lab/adapter-extension.js";
|
|
5
|
-
import type { SubjectPhaseEvent } from "../../subject/steps.js";
|
|
6
|
-
import type { DetachedTimers } from "../../substrates/detached.js";
|
|
7
|
-
import type { E2BDesktopModule, E2BDesktopSandbox } from "../../substrates/e2b/sdk.js";
|
|
8
|
-
import type { AutomaticAnalysisHooks, AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
|
|
5
|
+
import type { BrowserScorer } from "../../lab/adapter-extension.js";
|
|
6
|
+
import type { AutomaticAnalysisResult } from "../../analysis/automatic-completion.js";
|
|
9
7
|
import type { CuaActorDescriptor } from "../../actors/registry.js";
|
|
10
8
|
import type { CommsReceivingRun } from "../../comms/receiving.js";
|
|
11
9
|
import type { LabCommsEmail, LabCommsExternal, LabConfig } from "../../lab/types.js";
|
|
12
10
|
import type { DesktopResourceObservation } from "../../substrates/e2b/desktop-resources.js";
|
|
13
|
-
import type { ObserverResult
|
|
11
|
+
import type { ObserverResult } from "../../observer/render.js";
|
|
14
12
|
import type { ObserverRuntimeStreamUrl } from "../../observer/run-routes.js";
|
|
15
|
-
import type { RunBundle, RunScorerProvenance, RunSubjectProvenance, RunSubjectStateStepRecord } from "../../run/bundle.js";
|
|
13
|
+
import type { BundleRun, RunBundle, RunScorerProvenance, RunSubjectProvenance, RunSubjectStateStepRecord } from "../../run/bundle.js";
|
|
16
14
|
import type { RunScope } from "../../run/run.js";
|
|
17
15
|
import type { SharedWorldStateSnapshot } from "../../run/shared-world-evidence.js";
|
|
18
16
|
import type { LocalTreeArchive } from "../../subject/local-tree-archive.js";
|
|
19
|
-
import type { RunLabProvenance } from "../../run/status.js";
|
|
20
17
|
import type { LiveTraceFlush } from "../computer-use/live-flush.js";
|
|
21
18
|
import type { CuaParticipantDeps, DesktopParticipantRun, CuaRunBudget, ParticipantRunOutcome } from "../computer-use/types.js";
|
|
22
19
|
import type { ProvisionedPlaneSetup } from "./provisioned.js";
|
|
@@ -28,9 +25,8 @@ export declare const CONCURRENT_SHARED_WORLD_PROVIDER_METADATA: {
|
|
|
28
25
|
};
|
|
29
26
|
export declare const CONCURRENT_ATTRIBUTION_LIMITS: readonly ["concurrent", "best-effort-causal-attribution", "non-deterministic-shared-state", "window-and-snapshot-granularity", "contention-observed-not-proven-safe", "state-change-not-isolated-to-actors"];
|
|
30
27
|
export interface RunConcurrentSharedWorldLabOptions {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
lab?: RunLabProvenance;
|
|
28
|
+
/** Cancels post-run analysis only. */
|
|
29
|
+
analysisSignal?: AbortSignal;
|
|
34
30
|
cwd: string;
|
|
35
31
|
config: LabConfig;
|
|
36
32
|
/** Resolved upstream (scenario.mode + CLI override); defaults safe (dry-run). */
|
|
@@ -40,27 +36,44 @@ export interface RunConcurrentSharedWorldLabOptions {
|
|
|
40
36
|
onObserverReady?: (observer: ObserverResult & {
|
|
41
37
|
ok: true;
|
|
42
38
|
}) => Promise<void> | void;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
/** Keys and subject env for the run. Defaults to process.env. */
|
|
40
|
+
env?: Readonly<Record<string, string | undefined>>;
|
|
41
|
+
/**
|
|
42
|
+
* Runs after a sandbox exists and before anything is provisioned on it: the provisioned plane's
|
|
43
|
+
* subject sandbox, then each seat's desktop. The external-public plane has seats only.
|
|
44
|
+
*/
|
|
45
|
+
prepareDesktop?: NonNullable<RunLabHomes["prepareDesktop"]>;
|
|
46
|
+
/** Awaited after a participant's live stream starts, and again after its sandbox is gone. */
|
|
47
|
+
onStream?: NonNullable<RunLabHomes["onStream"]>;
|
|
48
|
+
/** Reports subject phases to onEvent; built by normalizeRunLabOptions. */
|
|
49
|
+
emit?: (event: LabEvent) => void;
|
|
50
|
+
/** Test seams. */
|
|
51
|
+
deps?: LabDeps;
|
|
52
|
+
/** Scores the assembled evidence: `RunLabOptions.scorer`, or the scorer the CLI loads. */
|
|
53
|
+
scorer?: BrowserScorer;
|
|
54
|
+
/** Present only when the scorer was CONFIG-DECLARED and loaded by the CLI (#316);
|
|
55
|
+
* core-stamped onto the bundle as evidence. Absent for library callers. */
|
|
46
56
|
scorerProvenance?: RunScorerProvenance;
|
|
47
57
|
}
|
|
48
58
|
/** What a shared-world run takes besides its plan. The plan carries the config, dry run and lab. */
|
|
49
59
|
export type SharedWorldRunInput = Omit<RunConcurrentSharedWorldLabOptions, "config" | "dryRun" | "lab">;
|
|
50
|
-
export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "
|
|
51
|
-
/** A local-agent brain's CLI is not on PATH
|
|
60
|
+
export type ConcurrentSharedWorldLabErrorCode = "HUMANISH_LAB_ANALYSIS_INVALID" | "HUMANISH_LAB_TASKS_UNSUPPORTED" | "HUMANISH_LAB_OPTION_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_FAILED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_ACTOR_UNSUPPORTED" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_INVALID" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_KEYS_MISSING"
|
|
61
|
+
/** A local-agent brain's CLI is not on `PATH`. */
|
|
52
62
|
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_AGENT_MISSING"
|
|
53
63
|
/** A local-agent brain's CLI is signed out, or could not report its sign-in status. */
|
|
54
64
|
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_AGENT_SIGNIN_REQUIRED"
|
|
55
65
|
/** A dollar cap that cannot be priced: an unpriced model, or a ChatGPT-account Codex brain. */
|
|
56
66
|
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_UNPRICED_CAP" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_SUBJECT_ENV_MISSING" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_GETHOST_UNAVAILABLE" | "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT" | "HUMANISH_RUN_ID_IN_USE"
|
|
57
67
|
/** A declared adopter-hosted comms catch (#328) did not answer as a humanish catch — fail closed
|
|
58
|
-
*
|
|
59
|
-
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE"
|
|
68
|
+
* before any actor spend, since the funnel would silently collect nothing. */
|
|
69
|
+
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_CATCH_UNREACHABLE"
|
|
70
|
+
/** comms.email.external.authTokenEnv names a token shorter than MIN_CATCH_TOKEN_LENGTH or not
|
|
71
|
+
* well-formed Unicode (src/comms/external-evidence.ts). Refused before the catch is probed. */
|
|
72
|
+
| "HUMANISH_CONCURRENT_SHARED_WORLD_LAB_COMMS_TOKEN_INVALID";
|
|
60
73
|
/** The two plane classes of the concurrent shared-world route (#164 phase 2). */
|
|
61
74
|
export type ConcurrentSharedWorldPlaneClass = "provisioned-getHost" | "external-public";
|
|
62
75
|
export declare const EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS: readonly ["concurrent", "best-effort-causal-attribution", "non-deterministic-shared-state", "window-and-snapshot-granularity", "contention-observed-not-proven-safe", "state-change-not-isolated-to-actors", "external-public-plane", "operator-attested-target-not-harness-controlled", "no-synthetic-attestation", "no-authoritative-shared-state-proof", "concurrency-by-temporal-co-occupancy-only"];
|
|
63
|
-
/** One persona's
|
|
76
|
+
/** One persona's outcome against the contended world (the "M of N" headline). */
|
|
64
77
|
export interface ConcurrentSharedWorldParticipantResult {
|
|
65
78
|
id: string;
|
|
66
79
|
index: number;
|
|
@@ -96,7 +109,7 @@ export interface ConcurrentSharedWorldLabResult extends AutomaticAnalysisResult
|
|
|
96
109
|
actor: string;
|
|
97
110
|
topology: "shared-world";
|
|
98
111
|
topologyMode: "concurrent";
|
|
99
|
-
/** The
|
|
112
|
+
/** The declared number of personas. */
|
|
100
113
|
roleCount: number;
|
|
101
114
|
/** Effective in-flight bound (execution.concurrency). */
|
|
102
115
|
concurrency: number;
|
|
@@ -104,17 +117,17 @@ export interface ConcurrentSharedWorldLabResult extends AutomaticAnalysisResult
|
|
|
104
117
|
runId: string;
|
|
105
118
|
/** The harness-minted getHost URL the actors drove (tokenless; live only). */
|
|
106
119
|
host?: string;
|
|
107
|
-
/** The
|
|
120
|
+
/** The one subject sandbox lifecycle proof. */
|
|
108
121
|
subjectSandbox?: {
|
|
109
122
|
sandboxId: string;
|
|
110
123
|
killed: boolean;
|
|
111
124
|
};
|
|
112
125
|
/** Whether ≥2 actor windows overlapped in time (proven concurrency; live only). */
|
|
113
126
|
overlapProven?: boolean;
|
|
114
|
-
/** Max
|
|
115
|
-
* 6-
|
|
127
|
+
/** Max participants observed live at the same instant (live only) — the honest simultaneity number; a
|
|
128
|
+
* 6-participant run capped at 3 reports 3 here, never 6 (#350). */
|
|
116
129
|
maxSimultaneousLanes?: number;
|
|
117
|
-
/** Subject provenance (invariant 5): the
|
|
130
|
+
/** Subject provenance (invariant 5): the one shared plane. */
|
|
118
131
|
subject?: RunSubjectProvenance;
|
|
119
132
|
roles: ConcurrentSharedWorldParticipantResult[];
|
|
120
133
|
observer?: ObserverResult;
|
|
@@ -145,11 +158,12 @@ type StartedRun = Extract<Awaited<ReturnType<RunScope["startRun"]>>, {
|
|
|
145
158
|
export interface PlaneContext {
|
|
146
159
|
plan: SharedWorldPlan;
|
|
147
160
|
input: SharedWorldRunInput;
|
|
148
|
-
/** Read
|
|
149
|
-
*
|
|
161
|
+
/** Read for the subject's serve URL, which each seat's subject names. Seats, their count and
|
|
162
|
+
* their host and entry come from the plan's participants. */
|
|
150
163
|
config: LabConfig;
|
|
151
164
|
descriptor: CuaActorDescriptor;
|
|
152
|
-
|
|
165
|
+
/** The run's test seams; empty outside tests. */
|
|
166
|
+
deps: LabDeps;
|
|
153
167
|
env: Record<string, string | undefined>;
|
|
154
168
|
concurrency: number;
|
|
155
169
|
runBudget: CuaRunBudget | undefined;
|
|
@@ -157,6 +171,8 @@ export interface PlaneContext {
|
|
|
157
171
|
openaiApiKey: string;
|
|
158
172
|
e2bApiKey: string;
|
|
159
173
|
scrubKnownValues: (text: string) => string;
|
|
174
|
+
/** The values scrubKnownValues removes. Real email receiving adds its secrets before seats start. */
|
|
175
|
+
knownSecretValues: readonly string[];
|
|
160
176
|
cwd: string;
|
|
161
177
|
run: StartedRun;
|
|
162
178
|
runId: string;
|
|
@@ -176,7 +192,7 @@ export interface PlaneContext {
|
|
|
176
192
|
}
|
|
177
193
|
/**
|
|
178
194
|
* What the seats feed while they run. A plane sets the attached Observer and starts the trace
|
|
179
|
-
* flush;
|
|
195
|
+
* flush; each seat's onStream appends stream URLs; the orchestrator reads all three at finish.
|
|
180
196
|
*/
|
|
181
197
|
export interface LiveParticipants {
|
|
182
198
|
observer?: ObserverResult & {
|
|
@@ -195,14 +211,12 @@ export interface ExternalCommsWiring {
|
|
|
195
211
|
export interface ConcurrentBundleArgs {
|
|
196
212
|
/** The run's judgment (judgeSharedWorldRun over the other fields). */
|
|
197
213
|
judgment: SharedWorldJudgment;
|
|
198
|
-
/**
|
|
199
|
-
|
|
214
|
+
/** The run this bundle belongs to; the bundle head reads its id, mode, start and lab. */
|
|
215
|
+
run: BundleRun;
|
|
200
216
|
plan: SharedWorldPlan;
|
|
201
217
|
descriptor: CuaActorDescriptor;
|
|
202
|
-
createdAt: string;
|
|
203
218
|
dryRun: boolean;
|
|
204
219
|
inProgress?: boolean;
|
|
205
|
-
runId: string;
|
|
206
220
|
source: RunBundle["source"];
|
|
207
221
|
actorSpecs: DesktopParticipantRun[];
|
|
208
222
|
actorResults: ActorRunResult[];
|
|
@@ -213,15 +227,15 @@ export interface ConcurrentBundleArgs {
|
|
|
213
227
|
hostDigest?: string;
|
|
214
228
|
/** Run-level digest-only comms-thread evidence path (humanish.comms-thread.v1), when a comms lab
|
|
215
229
|
* captured mail into the subject sandbox's catch. Registered on the first persona stream (it is a
|
|
216
|
-
* property of the
|
|
230
|
+
* property of the one shared app, and belongs to no single persona). */
|
|
217
231
|
commsArtifactPath?: string;
|
|
218
232
|
/** #164 phase 2: the plane-class discriminator (default provisioned-getHost, byte-stable). */
|
|
219
233
|
planeClass?: ConcurrentSharedWorldPlaneClass;
|
|
220
|
-
/** external-public only: sha256-16 of the
|
|
234
|
+
/** external-public only: sha256-16 of the observed origin the seats converged on (the convergence
|
|
221
235
|
* proof — what the seats actually reached, tolerant of a declared->observed redirect). */
|
|
222
236
|
publicOriginDigest?: string;
|
|
223
237
|
/** external-public only: sha256-16 of the operator-DECLARED plane origin (evidence/reference only;
|
|
224
|
-
*
|
|
238
|
+
* never asserted equal to the observed origin, since a cross-origin redirect is normal). */
|
|
225
239
|
declaredOriginDigest?: string;
|
|
226
240
|
/** external-public only: sha256-16 of the shared /lobby/CODE path all seats converged on. */
|
|
227
241
|
lobbyConvergenceDigest?: string;
|
|
@@ -236,6 +250,8 @@ export interface PlaneResults {
|
|
|
236
250
|
subjectCommit: string | undefined;
|
|
237
251
|
subjectSandboxId: string | undefined;
|
|
238
252
|
subjectKilled: boolean;
|
|
253
|
+
/** The subject sandbox's scrubbed release warning when its release is unconfirmed. */
|
|
254
|
+
subjectReleaseWarning: string | undefined;
|
|
239
255
|
subjectDesktop: SubjectDesktopUsage | undefined;
|
|
240
256
|
getHostUrl: string | undefined;
|
|
241
257
|
publicOriginDigest: string | undefined;
|
|
@@ -262,93 +278,4 @@ export interface FinishFacts {
|
|
|
262
278
|
stateSnapshots: SharedWorldStateSnapshot[];
|
|
263
279
|
declaredOriginDigest: string | undefined;
|
|
264
280
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Library-level hooks mirroring CuaActorLabHooks — the DI seams that let CI drive the FULL
|
|
267
|
-
* orchestration with fakes at $0/zero-network. The fake desktop module records create/kill BY id
|
|
268
|
-
* and exposes NO `list` method (the by-id teardown rail is then provable by construction).
|
|
269
|
-
*/
|
|
270
|
-
export interface SharedWorldLabHooks extends BrowserLabAdapterHooks {
|
|
271
|
-
/** Lazy-load the E2B desktop module (tests inject a fake; default loadE2BDesktopModule). */
|
|
272
|
-
loadDesktopModule?: () => Promise<E2BDesktopModule>;
|
|
273
|
-
/**
|
|
274
|
-
* Runs after a sandbox is created and before anything is provisioned on it. The provisioned
|
|
275
|
-
* plane calls it for the subject sandbox with no lane, then for each seat's desktop with its lane;
|
|
276
|
-
* the external-public plane calls it for the seats only.
|
|
277
|
-
*/
|
|
278
|
-
prepareDesktop?: (desktop: E2BDesktopSandbox, lane?: {
|
|
279
|
-
laneId: string;
|
|
280
|
-
laneIndex: number;
|
|
281
|
-
laneCount: number;
|
|
282
|
-
}) => Promise<void>;
|
|
283
|
-
/**
|
|
284
|
-
* Awaited after a seat's live desktop stream starts. The URL carries an auth key and must never
|
|
285
|
-
* be persisted. A rejection becomes a run warning, as on the computer-use route.
|
|
286
|
-
*/
|
|
287
|
-
onRuntimeStreamReady?: (stream: {
|
|
288
|
-
laneId: string;
|
|
289
|
-
sandboxId: string;
|
|
290
|
-
simId: string;
|
|
291
|
-
streamId: string;
|
|
292
|
-
url: string;
|
|
293
|
-
}) => Promise<void> | void;
|
|
294
|
-
/** Awaited after a seat's sandbox is gone, for seats whose stream started. Rejections are swallowed. */
|
|
295
|
-
onRuntimeStreamEnded?: (stream: {
|
|
296
|
-
laneId: string;
|
|
297
|
-
simId: string;
|
|
298
|
-
streamId: string;
|
|
299
|
-
}) => Promise<void> | void;
|
|
300
|
-
/** The per-seat computer-use session runner (default: the resolved actor descriptor's). */
|
|
301
|
-
runSession?: (options: CuaActorSessionOptions) => Promise<CuaLoopResult>;
|
|
302
|
-
/** The operator environment (keys + subject env values). Defaults to process.env. */
|
|
303
|
-
env?: Record<string, string | undefined>;
|
|
304
|
-
renderObserverFn?: typeof renderObserver;
|
|
305
|
-
/** Injected clock/sleep for the detached-step polling (tests only). */
|
|
306
|
-
detachedTimers?: DetachedTimers;
|
|
307
|
-
/**
|
|
308
|
-
* Subject-provisioning phase sink (mirrors CuaActorLabHooks.onPhase): one call per
|
|
309
|
-
* started/completed boundary during the ONE shared-plane provision (clone route: clone, install,
|
|
310
|
-
* build, serve start, ready, subject.state seed-step groups; local-tree route: upload, extract,
|
|
311
|
-
* install, build, serve start, ready, seed-step groups - no clone phase). Defaults to one stderr
|
|
312
|
-
* line per event. Override in tests to capture instead of writing to real stderr.
|
|
313
|
-
*/
|
|
314
|
-
onPhase?: (event: SubjectPhaseEvent) => void;
|
|
315
|
-
/**
|
|
316
|
-
* CONCURRENT route only (#164 phase 2): the harness clock used to MEASURE each actor's laneWindow
|
|
317
|
-
* [start,end] (default Date.now). The deterministic heart test does NOT override this — overlap is
|
|
318
|
-
* produced by a rendezvous latch in the fake runSession + measured by the REAL clock (FIX-1), so
|
|
319
|
-
* the windows are real, not injected. (A test may override only for non-overlap assertions.)
|
|
320
|
-
*/
|
|
321
|
-
now?: () => number;
|
|
322
|
-
/** CONCURRENT route only: the background stateSeries prober cadence (ms). Default 1000. */
|
|
323
|
-
proberCadenceMs?: number;
|
|
324
|
-
/**
|
|
325
|
-
* EXTERNAL-PUBLIC concurrent route only (#164 phase 2): the host-first handoff barrier deadline
|
|
326
|
-
* (ms). The host seat must surface a shared-session (/lobby/CODE) URL within this budget or the run
|
|
327
|
-
* fails closed with HUMANISH_CONCURRENT_SHARED_WORLD_LAB_HANDOFF_TIMEOUT and no follower opens.
|
|
328
|
-
* Default 120000 (also capped by execution.timeoutMs). Tests inject a short value to exercise the
|
|
329
|
-
* fail-closed path deterministically.
|
|
330
|
-
*/
|
|
331
|
-
handoffDeadlineMs?: number;
|
|
332
|
-
/**
|
|
333
|
-
* EXTERNAL-PUBLIC concurrent route only: the vision reader that extracts a /lobby/CODE off a seat's
|
|
334
|
-
* screenshot frame (the CDP-independent handoff relay + per-seat convergence observation). Defaults to
|
|
335
|
-
* the real single-frame OpenAI read (readLobbyCodeFromFrame). Tests inject a fake so the barrier's
|
|
336
|
-
* handoff + convergence proof can be exercised deterministically without a live vision call.
|
|
337
|
-
*/
|
|
338
|
-
readLobbyCodeFromFrame?: (frame: Buffer, apiKey: string) => Promise<string | undefined>;
|
|
339
|
-
/**
|
|
340
|
-
* Local-tree packing DI seam (tests only, no npm dependency needed to exercise the route):
|
|
341
|
-
* defaults to createLocalTreeArchive(root, opts) plus a host-side read of the produced archive
|
|
342
|
-
* file into an ArrayBuffer (the SAME default routes/computer-use/route.ts uses). Called ONCE per run, before
|
|
343
|
-
* the ONE shared-plane sandbox is created, on the live local-tree route.
|
|
344
|
-
*/
|
|
345
|
-
packLocalTree?: (args: {
|
|
346
|
-
root: string;
|
|
347
|
-
extraExclude?: string[];
|
|
348
|
-
maxArchiveBytes?: number;
|
|
349
|
-
}) => Promise<{
|
|
350
|
-
archive: LocalTreeArchive;
|
|
351
|
-
buffer: ArrayBuffer;
|
|
352
|
-
}>;
|
|
353
|
-
}
|
|
354
281
|
export {};
|
|
@@ -5,7 +5,7 @@ export const CONCURRENT_SHARED_WORLD_PROVIDER_METADATA = {
|
|
|
5
5
|
mode: "concurrent-shared-world-lab",
|
|
6
6
|
tool: "humanish",
|
|
7
7
|
};
|
|
8
|
-
// The verify-enforced
|
|
8
|
+
// The verify-enforced concurrent attribution ceiling. Mirrored in
|
|
9
9
|
// verify/shared-world-concurrent.ts CONCURRENT_REQUIRED_LIMITS.
|
|
10
10
|
export const CONCURRENT_ATTRIBUTION_LIMITS = [
|
|
11
11
|
"concurrent",
|
|
@@ -16,7 +16,7 @@ export const CONCURRENT_ATTRIBUTION_LIMITS = [
|
|
|
16
16
|
"state-change-not-isolated-to-actors",
|
|
17
17
|
];
|
|
18
18
|
// EXTERNAL-PUBLIC plane class: the honest-downgrade attribution ceiling. The concurrent family
|
|
19
|
-
// (an honest ceiling)
|
|
19
|
+
// (an honest ceiling) plus the mandatory external-public disclosures, mirrored in the required
|
|
20
20
|
// set in verify/shared-world-concurrent.ts (CONCURRENT_ATTRIBUTION_LIMITS +
|
|
21
21
|
// EXTERNAL_PUBLIC_EXTRA_LIMITS). Verify fails closed on a missing one.
|
|
22
22
|
export const EXTERNAL_PUBLIC_ATTRIBUTION_LIMITS = [
|