humanish 0.107.0 → 0.109.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/ARCHITECTURE.md +73 -69
- package/CHANGELOG.md +27 -0
- package/CONTEXT.md +51 -44
- package/README.md +148 -175
- package/SECURITY.md +16 -26
- package/TELEMETRY.md +8 -6
- package/dist/actors/affordance.d.ts +4 -4
- package/dist/actors/affordance.js +12 -12
- package/dist/actors/agent-session.d.ts +2 -2
- package/dist/actors/agent-session.js +7 -7
- package/dist/actors/codex/app-server-actor-trace.d.ts +1 -1
- package/dist/actors/codex/app-server-actor-trace.js +1 -1
- package/dist/actors/codex/app-server-trace.js +2 -1
- package/dist/actors/codex/app-server-ui.js +1 -1
- package/dist/actors/codex/codex-admission.d.ts +91 -0
- package/dist/actors/codex/codex-admission.js +150 -0
- package/dist/actors/codex/restricted-executable.d.ts +4 -4
- package/dist/actors/codex/restricted-executable.js +8 -8
- package/dist/actors/codex/restricted-launch.d.ts +2 -1
- package/dist/actors/codex/restricted-launch.js +1 -1
- package/dist/actors/codex/restricted-participant.js +20 -18
- package/dist/actors/codex/restricted-policy.d.ts +2 -2
- package/dist/actors/codex/restricted-policy.js +2 -2
- package/dist/actors/codex/restricted-session.d.ts +3 -3
- package/dist/actors/codex/restricted-session.js +10 -5
- package/dist/actors/computer-use/actor.d.ts +18 -18
- package/dist/actors/computer-use/actor.js +4 -4
- package/dist/actors/computer-use/admission-limit.d.ts +3 -3
- package/dist/actors/computer-use/admission-limit.js +4 -4
- package/dist/actors/computer-use/executor-error.d.ts +2 -2
- package/dist/actors/computer-use/executor-error.js +3 -3
- package/dist/actors/computer-use/loop/actions.d.ts +3 -3
- package/dist/actors/computer-use/loop/actions.js +15 -15
- package/dist/actors/computer-use/loop/backstop.d.ts +3 -3
- package/dist/actors/computer-use/loop/backstop.js +14 -12
- package/dist/actors/computer-use/loop/debrief.js +2 -2
- package/dist/actors/computer-use/loop/ending.d.ts +6 -6
- package/dist/actors/computer-use/loop/ending.js +18 -17
- package/dist/actors/computer-use/loop/observation.d.ts +2 -2
- package/dist/actors/computer-use/loop/observation.js +15 -14
- package/dist/actors/computer-use/loop/provider-call.d.ts +1 -1
- package/dist/actors/computer-use/loop/provider-call.js +12 -12
- package/dist/actors/computer-use/loop/session.d.ts +4 -4
- package/dist/actors/computer-use/loop/session.js +4 -4
- package/dist/actors/computer-use/loop/spend.d.ts +1 -1
- package/dist/actors/computer-use/loop/spend.js +1 -1
- package/dist/actors/computer-use/loop/trace.js +11 -9
- package/dist/actors/computer-use/loop/types.d.ts +47 -45
- package/dist/actors/computer-use/loop/usage.d.ts +2 -2
- package/dist/actors/computer-use/loop/usage.js +2 -2
- package/dist/actors/computer-use/loop.d.ts +6 -1
- package/dist/actors/computer-use/loop.js +26 -4
- package/dist/actors/computer-use/openai-context.d.ts +37 -0
- package/dist/actors/computer-use/openai-context.js +214 -0
- package/dist/actors/computer-use/openai-provider.d.ts +13 -10
- package/dist/actors/computer-use/openai-provider.js +52 -41
- package/dist/actors/computer-use/openai-requests.d.ts +36 -10
- package/dist/actors/computer-use/openai-requests.js +82 -15
- package/dist/actors/computer-use/openai-wire.d.ts +19 -7
- package/dist/actors/computer-use/openai-wire.js +36 -34
- package/dist/actors/computer-use/provider-error.d.ts +4 -4
- package/dist/actors/computer-use/provider-error.js +6 -6
- package/dist/actors/contract.d.ts +82 -47
- package/dist/actors/contract.js +30 -24
- package/dist/actors/local-agent/claude-session.d.ts +1 -1
- package/dist/actors/local-agent/claude-session.js +13 -12
- package/dist/actors/local-agent/cli.d.ts +9 -7
- package/dist/actors/local-agent/cli.js +24 -28
- package/dist/actors/local-agent/readiness.d.ts +2 -2
- package/dist/actors/local-agent/readiness.js +4 -4
- package/dist/actors/reasoning-effort.js +8 -8
- package/dist/actors/registry.d.ts +12 -12
- package/dist/actors/registry.js +21 -20
- package/dist/actors/scripted-browser/actor.d.ts +10 -10
- package/dist/actors/scripted-browser/actor.js +17 -17
- package/dist/actors/scripted-browser/browser-command.js +1 -1
- package/dist/actors/scripted-browser/steps.js +1 -1
- package/dist/actors/scripted-browser/types.d.ts +1 -1
- package/dist/actors/stop-conditions.d.ts +1 -1
- package/dist/analysis/automatic-completion.d.ts +7 -7
- package/dist/analysis/automatic-completion.js +1 -1
- package/dist/analysis/automatic-config.d.ts +6 -6
- package/dist/analysis/automatic-config.js +1 -1
- package/dist/analysis/codex-config.d.ts +6 -2
- package/dist/analysis/codex-config.js +22 -14
- package/dist/analysis/execute.d.ts +1 -1
- package/dist/analysis/execute.js +1 -1
- package/dist/analysis/service.js +5 -5
- package/dist/analysis/types.d.ts +6 -0
- package/dist/browser-control/client.js +16 -16
- package/dist/browser-control/dispatcher.js +4 -4
- package/dist/browser-control/protocol.js +14 -14
- package/dist/browser-control/recording-transfer.js +4 -4
- package/dist/browser-control/transport.js +7 -7
- package/dist/cli/commands/analysis-signals.d.ts +2 -2
- package/dist/cli/commands/analyze.js +19 -16
- package/dist/cli/commands/codex.js +9 -9
- package/dist/cli/commands/comms.js +48 -35
- package/dist/cli/commands/feedback.js +20 -21
- package/dist/cli/commands/migrate.d.ts +4 -0
- package/dist/cli/commands/migrate.js +65 -0
- package/dist/cli/commands/observe.d.ts +0 -1
- package/dist/cli/commands/observe.js +136 -112
- package/dist/cli/commands/run-command.d.ts +10 -0
- package/dist/cli/commands/run-command.js +85 -0
- package/dist/cli/commands/runs.js +136 -139
- package/dist/cli/commands/setup.d.ts +2 -2
- package/dist/cli/commands/setup.js +27 -24
- package/dist/cli/commands/study-format.d.ts +9 -0
- package/dist/cli/commands/{lab-format.js → study-format.js} +39 -27
- package/dist/cli/commands/{lab-route-computer-use.d.ts → study-route-computer-use.d.ts} +6 -6
- package/dist/cli/commands/{lab-route-computer-use.js → study-route-computer-use.js} +17 -18
- package/dist/cli/commands/{lab-route-open.d.ts → study-route-open.d.ts} +4 -4
- package/dist/cli/commands/{lab-route-open.js → study-route-open.js} +2 -2
- package/dist/cli/commands/{lab-route-preview.d.ts → study-route-preview.d.ts} +7 -7
- package/dist/cli/commands/{lab-route-preview.js → study-route-preview.js} +7 -6
- package/dist/cli/commands/study-route-run.d.ts +19 -0
- package/dist/cli/commands/{lab-route-run.js → study-route-run.js} +6 -6
- package/dist/cli/commands/study-route-scripted.d.ts +17 -0
- package/dist/cli/commands/{lab-route-scripted.js → study-route-scripted.js} +4 -4
- package/dist/cli/commands/{lab-route-shared-world.d.ts → study-route-shared-world.d.ts} +5 -5
- package/dist/cli/commands/{lab-route-shared-world.js → study-route-shared-world.js} +10 -10
- package/dist/cli/commands/study-route-terminal.d.ts +17 -0
- package/dist/cli/commands/{lab-route-terminal.js → study-route-terminal.js} +4 -4
- package/dist/cli/commands/study-run.d.ts +9 -0
- package/dist/cli/commands/{lab-run.js → study-run.js} +44 -45
- package/dist/cli/commands/{lab-scorer.d.ts → study-scorer.d.ts} +7 -7
- package/dist/cli/commands/{lab-scorer.js → study-scorer.js} +2 -2
- package/dist/cli/commands/study.d.ts +3 -0
- package/dist/cli/commands/study.js +146 -0
- package/dist/cli/commands/tui.d.ts +4 -4
- package/dist/cli/commands/tui.js +31 -31
- package/dist/cli/commands/watch.js +71 -121
- package/dist/cli/deprecations.d.ts +6 -0
- package/dist/cli/deprecations.js +18 -0
- package/dist/cli/doctor.d.ts +18 -8
- package/dist/cli/doctor.js +114 -59
- package/dist/cli/first-run-path.d.ts +15 -13
- package/dist/cli/first-run-path.js +35 -33
- package/dist/cli/io.d.ts +44 -9
- package/dist/cli/io.js +98 -23
- package/dist/cli/observer-follow.d.ts +3 -3
- package/dist/cli/observer-follow.js +6 -7
- package/dist/cli/orientation.d.ts +10 -7
- package/dist/cli/orientation.js +89 -47
- package/dist/cli/product-sentence.d.ts +6 -0
- package/dist/cli/product-sentence.js +6 -0
- package/dist/cli/program.d.ts +6 -1
- package/dist/cli/program.js +111 -43
- package/dist/cli/telemetry.d.ts +16 -16
- package/dist/cli/telemetry.js +46 -44
- package/dist/cli.js +1 -1
- package/dist/comms/capture-surface.d.ts +13 -12
- package/dist/comms/capture-surface.js +23 -22
- package/dist/comms/catch-host.d.ts +7 -7
- package/dist/comms/catch-host.js +17 -17
- package/dist/comms/connections.d.ts +1 -1
- package/dist/comms/connections.js +2 -2
- package/dist/comms/email-catch.d.ts +3 -3
- package/dist/comms/email-catch.js +8 -8
- package/dist/comms/external-evidence.d.ts +5 -5
- package/dist/comms/external-evidence.js +5 -4
- package/dist/comms/extract.js +2 -2
- package/dist/comms/fake-inbox.d.ts +3 -3
- package/dist/comms/fake-inbox.js +3 -3
- package/dist/comms/receiving-render.d.ts +1 -1
- package/dist/comms/receiving-render.js +2 -2
- package/dist/comms/receiving-runtime.d.ts +4 -4
- package/dist/comms/sandbox-catch-script.d.ts +6 -6
- package/dist/comms/sandbox-catch-script.js +6 -6
- package/dist/comms/sandbox-catch.d.ts +38 -39
- package/dist/comms/sandbox-catch.js +36 -37
- package/dist/comms/setup.d.ts +2 -2
- package/dist/comms/setup.js +56 -25
- package/dist/comms/thread-evidence.d.ts +1 -1
- package/dist/comms/thread-evidence.js +6 -6
- package/dist/comms/types.d.ts +6 -6
- package/dist/comms/types.js +3 -3
- package/dist/evidence/frame-signature.d.ts +1 -1
- package/dist/evidence/frame-signature.js +4 -4
- package/dist/evidence/redaction.d.ts +3 -3
- package/dist/evidence/redaction.js +4 -4
- package/dist/feedback/draft.js +38 -80
- package/dist/feedback/export-bundle.js +1 -1
- package/dist/feedback/export.d.ts +5 -1
- package/dist/feedback/export.js +10 -10
- package/dist/feedback/feedback.d.ts +2 -2
- package/dist/feedback/feedback.js +21 -3
- package/dist/feedback/proof.d.ts +1 -1
- package/dist/feedback/proof.js +2 -2
- package/dist/guest/bootstrap.js +6 -6
- package/dist/guest/browser-tools.js +8 -8
- package/dist/guest/chromium-text.js +19 -19
- package/dist/guest/desktop-executor.d.ts +2 -2
- package/dist/guest/desktop-executor.js +20 -20
- package/dist/guest/desktop-keys.js +4 -4
- package/dist/guest/desktop-media.d.ts +2 -2
- package/dist/guest/desktop-media.js +16 -16
- package/dist/guest/desktop-native.d.ts +1 -1
- package/dist/guest/desktop-native.js +10 -10
- package/dist/guest/runtime-desktop.js +2 -2
- package/dist/guest/runtime-processes.d.ts +2 -2
- package/dist/guest/runtime-processes.js +2 -2
- package/dist/guest/runtime.js +6 -6
- package/dist/index.d.ts +14 -14
- package/dist/index.js +8 -8
- package/dist/keys/key-resolution.d.ts +5 -5
- package/dist/keys/key-resolution.js +23 -23
- package/dist/observer/artifact.d.ts +2 -2
- package/dist/observer/artifact.js +7 -7
- package/dist/observer/data.d.ts +6 -6
- package/dist/observer/data.js +5 -4
- package/dist/observer/exposure.d.ts +1 -1
- package/dist/observer/exposure.js +11 -11
- package/dist/observer/http.js +1 -1
- package/dist/observer/library.d.ts +3 -1
- package/dist/observer/library.js +8 -3
- package/dist/observer/listen.js +5 -4
- package/dist/observer/render.d.ts +1 -1
- package/dist/observer/render.js +17 -6
- package/dist/observer/run-routes.d.ts +4 -3
- package/dist/observer/run-routes.js +38 -13
- package/dist/observer/serve.d.ts +1 -1
- package/dist/observer/serve.js +7 -3
- package/dist/observer/tunnel.js +1 -1
- package/dist/observer-app.html +4 -4
- package/dist/routes/computer-use/bundle-parts.d.ts +9 -9
- package/dist/routes/computer-use/bundle-parts.js +18 -17
- package/dist/routes/computer-use/bundle.d.ts +2 -2
- package/dist/routes/computer-use/bundle.js +10 -9
- package/dist/routes/computer-use/e2b-desktop/comms.d.ts +6 -6
- package/dist/routes/computer-use/e2b-desktop/comms.js +18 -17
- package/dist/routes/computer-use/e2b-desktop/desktop.js +4 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.d.ts +5 -4
- package/dist/routes/computer-use/e2b-desktop/fidelity.js +11 -10
- package/dist/routes/computer-use/e2b-desktop/prepare.d.ts +1 -1
- package/dist/routes/computer-use/e2b-desktop/prepare.js +10 -10
- package/dist/routes/computer-use/e2b-desktop/start.js +7 -7
- package/dist/routes/computer-use/e2b-desktop/state.d.ts +2 -2
- package/dist/routes/computer-use/e2b-desktop/teardown.js +2 -2
- package/dist/routes/computer-use/external-comms.d.ts +4 -4
- package/dist/routes/computer-use/external-comms.js +1 -1
- package/dist/routes/computer-use/fanout-bundle.js +27 -26
- package/dist/routes/computer-use/fanout-records.js +12 -13
- package/dist/routes/computer-use/live-flush.d.ts +4 -4
- package/dist/routes/computer-use/live-flush.js +6 -6
- package/dist/routes/computer-use/live-phase.d.ts +5 -4
- package/dist/routes/computer-use/live-phase.js +8 -8
- package/dist/routes/computer-use/local-tree-pack.d.ts +5 -5
- package/dist/routes/computer-use/local-tree-pack.js +1 -1
- package/dist/routes/computer-use/local-vm.d.ts +8 -8
- package/dist/routes/computer-use/local-vm.js +3 -3
- package/dist/routes/computer-use/participant-desktop.d.ts +7 -7
- package/dist/routes/computer-use/participant-desktop.js +5 -5
- package/dist/routes/computer-use/participant-execution.d.ts +4 -4
- package/dist/routes/computer-use/participant-execution.js +10 -10
- package/dist/routes/computer-use/participant-model.d.ts +6 -0
- package/dist/routes/computer-use/participant-model.js +33 -15
- package/dist/routes/computer-use/participant-prompt.d.ts +15 -15
- package/dist/routes/computer-use/participant-prompt.js +9 -9
- package/dist/routes/computer-use/participant-runs.d.ts +16 -16
- package/dist/routes/computer-use/participant-runs.js +26 -25
- package/dist/routes/computer-use/plan.d.ts +12 -12
- package/dist/routes/computer-use/plan.js +42 -42
- package/dist/routes/computer-use/preflight.d.ts +5 -5
- package/dist/routes/computer-use/preflight.js +25 -25
- package/dist/routes/computer-use/rerun-selection.d.ts +1 -1
- package/dist/routes/computer-use/rerun-selection.js +4 -3
- package/dist/routes/computer-use/result.d.ts +4 -4
- package/dist/routes/computer-use/result.js +22 -21
- package/dist/routes/computer-use/route.d.ts +12 -11
- package/dist/routes/computer-use/route.js +31 -30
- package/dist/routes/computer-use/self-report.d.ts +7 -7
- package/dist/routes/computer-use/self-report.js +32 -32
- package/dist/routes/computer-use/setup.d.ts +23 -23
- package/dist/routes/computer-use/setup.js +28 -29
- package/dist/routes/computer-use/single-bundle.d.ts +11 -11
- package/dist/routes/computer-use/single-bundle.js +40 -41
- package/dist/routes/computer-use/subject-projection.d.ts +4 -4
- package/dist/routes/computer-use/subject-projection.js +6 -6
- package/dist/routes/computer-use/types.d.ts +71 -73
- package/dist/routes/computer-use/types.js +12 -12
- package/dist/routes/preview.d.ts +13 -7
- package/dist/routes/preview.js +11 -7
- package/dist/routes/scripted/bundle.d.ts +7 -7
- package/dist/routes/scripted/bundle.js +20 -18
- package/dist/routes/scripted/plan.d.ts +8 -8
- package/dist/routes/scripted/plan.js +13 -13
- package/dist/routes/scripted/result.d.ts +3 -3
- package/dist/routes/scripted/result.js +13 -13
- package/dist/routes/scripted/route.d.ts +9 -9
- package/dist/routes/scripted/route.js +15 -16
- package/dist/routes/scripted/scenario.d.ts +1 -1
- package/dist/routes/scripted/scenario.js +5 -5
- package/dist/routes/scripted/setup.d.ts +6 -6
- package/dist/routes/scripted/setup.js +8 -8
- package/dist/routes/scripted/subject.d.ts +5 -5
- package/dist/routes/scripted/subject.js +4 -4
- package/dist/routes/scripted/surface-records.d.ts +1 -1
- package/dist/routes/scripted/surface-records.js +4 -4
- package/dist/routes/scripted/surface-sessions.d.ts +3 -3
- package/dist/routes/scripted/types.d.ts +18 -20
- package/dist/routes/scripted/types.js +2 -2
- package/dist/routes/shared-world/bundle-records.js +11 -10
- package/dist/routes/shared-world/bundle.d.ts +5 -5
- package/dist/routes/shared-world/bundle.js +46 -43
- package/dist/routes/shared-world/checkpoints.d.ts +4 -4
- package/dist/routes/shared-world/checkpoints.js +2 -2
- package/dist/routes/shared-world/comms.d.ts +14 -14
- package/dist/routes/shared-world/comms.js +19 -18
- package/dist/routes/shared-world/external-public.d.ts +4 -3
- package/dist/routes/shared-world/external-public.js +16 -12
- package/dist/routes/shared-world/handoff.d.ts +7 -6
- package/dist/routes/shared-world/handoff.js +65 -57
- package/dist/routes/shared-world/lobby-code.d.ts +2 -2
- package/dist/routes/shared-world/lobby-code.js +9 -9
- package/dist/routes/shared-world/participant-specs.d.ts +10 -9
- package/dist/routes/shared-world/participant-specs.js +38 -31
- package/dist/routes/shared-world/plan.d.ts +9 -9
- package/dist/routes/shared-world/plan.js +16 -16
- package/dist/routes/shared-world/provenance.d.ts +2 -2
- package/dist/routes/shared-world/provenance.js +2 -2
- package/dist/routes/shared-world/provisioned.d.ts +8 -8
- package/dist/routes/shared-world/provisioned.js +18 -17
- package/dist/routes/shared-world/result.d.ts +6 -6
- package/dist/routes/shared-world/result.js +29 -29
- package/dist/routes/shared-world/route.d.ts +11 -11
- package/dist/routes/shared-world/route.js +40 -39
- package/dist/routes/shared-world/setup.d.ts +16 -16
- package/dist/routes/shared-world/setup.js +23 -23
- package/dist/routes/shared-world/types.d.ts +55 -53
- package/dist/routes/shared-world/types.js +4 -4
- package/dist/routes/terminal/adapter.d.ts +5 -5
- package/dist/routes/terminal/adapter.js +9 -9
- package/dist/routes/terminal/bundle.d.ts +13 -13
- package/dist/routes/terminal/bundle.js +28 -27
- package/dist/routes/terminal/credentials.d.ts +8 -8
- package/dist/routes/terminal/credentials.js +12 -12
- package/dist/routes/terminal/dry-run.d.ts +4 -4
- package/dist/routes/terminal/dry-run.js +12 -12
- package/dist/routes/terminal/encoding.js +2 -2
- package/dist/routes/terminal/ledger.d.ts +5 -5
- package/dist/routes/terminal/ledger.js +14 -14
- package/dist/routes/terminal/lifetime.d.ts +1 -1
- package/dist/routes/terminal/lifetime.js +1 -1
- package/dist/routes/terminal/live-finish.d.ts +2 -2
- package/dist/routes/terminal/live-finish.js +10 -10
- package/dist/routes/terminal/live-sandbox.d.ts +2 -2
- package/dist/routes/terminal/live-sandbox.js +15 -15
- package/dist/routes/terminal/participant-text.js +2 -1
- package/dist/routes/terminal/persona.d.ts +2 -2
- package/dist/routes/terminal/persona.js +3 -3
- package/dist/routes/terminal/plan.d.ts +7 -7
- package/dist/routes/terminal/plan.js +15 -15
- package/dist/routes/terminal/recorder.js +2 -2
- package/dist/routes/terminal/result.d.ts +5 -5
- package/dist/routes/terminal/result.js +14 -14
- package/dist/routes/terminal/route.d.ts +9 -9
- package/dist/routes/terminal/route.js +19 -20
- package/dist/routes/terminal/sandbox.d.ts +1 -1
- package/dist/routes/terminal/sandbox.js +1 -1
- package/dist/routes/terminal/session.d.ts +5 -5
- package/dist/routes/terminal/session.js +14 -13
- package/dist/routes/terminal/token-usage.d.ts +1 -1
- package/dist/routes/terminal/token-usage.js +7 -8
- package/dist/routes/terminal/trace.d.ts +4 -4
- package/dist/routes/terminal/trace.js +2 -2
- package/dist/routes/terminal/types.d.ts +48 -50
- package/dist/routes/terminal/types.js +5 -5
- package/dist/run/bundle-shape.js +3 -3
- package/dist/run/bundle.d.ts +49 -49
- package/dist/run/bundle.js +3 -2
- package/dist/run/cost-summary.js +3 -3
- package/dist/run/costs.d.ts +23 -0
- package/dist/run/costs.js +79 -44
- package/dist/run/detail.d.ts +6 -6
- package/dist/run/detail.js +4 -4
- package/dist/run/dry-run-inputs.d.ts +1 -1
- package/dist/run/dry-run-inputs.js +2 -2
- package/dist/run/dry-run.js +20 -20
- package/dist/run/judge.d.ts +19 -13
- package/dist/run/judge.js +18 -8
- package/dist/run/outcomes.d.ts +1 -1
- package/dist/run/participant.d.ts +1 -1
- package/dist/run/paths.d.ts +1 -1
- package/dist/run/paths.js +1 -1
- package/dist/run/preflight-receipts.js +1 -1
- package/dist/run/pricing.d.ts +11 -6
- package/dist/run/pricing.js +22 -15
- package/dist/run/projection.d.ts +46 -46
- package/dist/run/projection.js +57 -57
- package/dist/run/reclaim.d.ts +1 -1
- package/dist/run/reclaim.js +3 -3
- package/dist/run/results.d.ts +5 -5
- package/dist/run/run-cost.d.ts +53 -0
- package/dist/run/run-cost.js +105 -0
- package/dist/run/run-index-analysis.d.ts +15 -0
- package/dist/run/run-index-analysis.js +77 -0
- package/dist/run/run-index.d.ts +19 -7
- package/dist/run/run-index.js +77 -64
- package/dist/run/run-not-found.d.ts +5 -0
- package/dist/run/run-not-found.js +15 -0
- package/dist/run/run.d.ts +6 -5
- package/dist/run/run.js +3 -3
- package/dist/run/sandbox-receipts.d.ts +2 -2
- package/dist/run/sandbox-receipts.js +3 -3
- package/dist/run/shared-world-evidence.d.ts +37 -36
- package/dist/run/shared-world-evidence.js +4 -4
- package/dist/run/shared-world-shape.d.ts +1 -1
- package/dist/run/shared-world-shape.js +7 -7
- package/dist/run/stats.d.ts +14 -8
- package/dist/run/stats.js +121 -63
- package/dist/run/status.d.ts +16 -29
- package/dist/run/status.js +10 -29
- package/dist/run/stored-runs.js +2 -1
- package/dist/run/stream-shape.js +1 -1
- package/dist/run/streams.d.ts +7 -7
- package/dist/run/study-provenance.d.ts +49 -0
- package/dist/run/study-provenance.js +66 -0
- package/dist/run/study-result.d.ts +11 -0
- package/dist/run/study-result.js +9 -0
- package/dist/run/text.d.ts +2 -0
- package/dist/run/text.js +4 -0
- package/dist/run-study.d.ts +112 -0
- package/dist/{run-lab.js → run-study.js} +52 -47
- package/dist/{lab → study}/adapter-extension.d.ts +15 -27
- package/dist/{lab → study}/adapter-extension.js +10 -45
- package/dist/{lab → study}/adapter-scorer-loader.d.ts +17 -17
- package/dist/{lab → study}/adapter-scorer-loader.js +34 -34
- package/dist/study/composition-rules.d.ts +7 -0
- package/dist/{lab → study}/composition-rules.js +53 -53
- package/dist/study/config.d.ts +15 -0
- package/dist/{lab → study}/config.js +98 -41
- package/dist/study/convert.d.ts +33 -0
- package/dist/study/convert.js +432 -0
- package/dist/{lab → study}/device-presets.d.ts +10 -10
- package/dist/{lab → study}/device-presets.js +11 -11
- package/dist/study/discover.d.ts +75 -0
- package/dist/{lab → study}/discover.js +134 -95
- package/dist/{lab → study}/doctor.d.ts +19 -12
- package/dist/{lab → study}/doctor.js +58 -20
- package/dist/study/field-paths.d.ts +12 -0
- package/dist/study/field-paths.js +126 -0
- package/dist/study/files.d.ts +26 -0
- package/dist/study/files.js +44 -0
- package/dist/{lab → study}/init-templates.d.ts +2 -2
- package/dist/study/init-templates.js +421 -0
- package/dist/{lab → study}/init.d.ts +2 -2
- package/dist/{lab → study}/init.js +46 -11
- package/dist/study/keys.d.ts +4 -0
- package/dist/{lab → study}/keys.js +46 -12
- package/dist/study/migrate.d.ts +48 -0
- package/dist/study/migrate.js +408 -0
- package/dist/study/owned-files.d.ts +38 -0
- package/dist/study/owned-files.js +182 -0
- package/dist/{lab → study}/parse/actors.d.ts +5 -5
- package/dist/{lab → study}/parse/actors.js +14 -14
- package/dist/study/parse/comms.d.ts +12 -0
- package/dist/{lab → study}/parse/comms.js +5 -5
- package/dist/study/parse/execution.d.ts +19 -0
- package/dist/{lab → study}/parse/execution.js +13 -13
- package/dist/study/parse/study-v3.d.ts +21 -0
- package/dist/study/parse/study-v3.js +259 -0
- package/dist/study/parse/subject-state.d.ts +30 -0
- package/dist/{lab → study}/parse/subject-state.js +19 -19
- package/dist/{lab → study}/parse/subject.d.ts +3 -3
- package/dist/{lab → study}/parse/subject.js +34 -34
- package/dist/{lab → study}/parse/values.d.ts +3 -3
- package/dist/{lab → study}/parse/values.js +3 -3
- package/dist/{lab → study}/persona-resolve.d.ts +8 -8
- package/dist/{lab → study}/persona-resolve.js +6 -6
- package/dist/{lab → study}/plan-base.d.ts +7 -7
- package/dist/{lab → study}/plan-base.js +1 -1
- package/dist/{lab → study}/plan-participants.d.ts +12 -12
- package/dist/{lab → study}/plan-participants.js +4 -4
- package/dist/{lab → study}/plan-types.d.ts +31 -31
- package/dist/{lab → study}/plan-types.js +2 -2
- package/dist/study/plan.d.ts +13 -0
- package/dist/study/plan.js +101 -0
- package/dist/study/preflight-probes.d.ts +3 -0
- package/dist/{lab → study}/preflight-probes.js +20 -19
- package/dist/study/preflight-result.d.ts +8 -0
- package/dist/{lab → study}/preflight-result.js +5 -4
- package/dist/study/preflight.d.ts +94 -0
- package/dist/{lab → study}/preflight.js +12 -12
- package/dist/{lab → study}/requirements.d.ts +3 -3
- package/dist/{lab → study}/requirements.js +1 -1
- package/dist/study/route-inputs.d.ts +28 -0
- package/dist/{lab → study}/route-inputs.js +1 -1
- package/dist/{lab → study}/routing.d.ts +39 -33
- package/dist/{lab → study}/routing.js +60 -29
- package/dist/{lab/run-lab-events.d.ts → study/run-study-events.d.ts} +10 -13
- package/dist/{lab/run-lab-events.js → study/run-study-events.js} +3 -9
- package/dist/{lab/run-lab-homes.d.ts → study/run-study-homes.d.ts} +21 -18
- package/dist/{lab/run-lab-homes.js → study/run-study-homes.js} +1 -1
- package/dist/study/run-study-options.d.ts +28 -0
- package/dist/{lab/run-lab-options.js → study/run-study-options.js} +29 -25
- package/dist/{lab/lab-deps.d.ts → study/study-deps.d.ts} +8 -13
- package/dist/{lab/lab-deps.js → study/study-deps.js} +2 -2
- package/dist/{lab → study}/summary.d.ts +16 -15
- package/dist/{lab → study}/summary.js +21 -21
- package/dist/{lab → study}/tasks.d.ts +18 -18
- package/dist/{lab → study}/tasks.js +14 -14
- package/dist/{lab → study}/types.d.ts +202 -196
- package/dist/{lab → study}/types.js +3 -1
- package/dist/{lab → study}/validation.d.ts +27 -27
- package/dist/{lab → study}/validation.js +53 -51
- package/dist/study/warnings.d.ts +12 -0
- package/dist/{lab → study}/warnings.js +62 -34
- package/dist/subject/clone.d.ts +7 -7
- package/dist/subject/clone.js +2 -2
- package/dist/subject/desktop-cli.d.ts +1 -1
- package/dist/subject/desktop-cli.js +2 -2
- package/dist/subject/local-tree-archive.d.ts +2 -2
- package/dist/subject/local-tree-archive.js +4 -4
- package/dist/subject/local-tree.d.ts +4 -4
- package/dist/subject/node-bootstrap.js +1 -1
- package/dist/subject/runtime.js +9 -10
- package/dist/subject/serve.d.ts +5 -5
- package/dist/subject/serve.js +3 -3
- package/dist/subject/state.d.ts +4 -4
- package/dist/subject/state.js +1 -1
- package/dist/subject/steps.d.ts +6 -6
- package/dist/subject/steps.js +5 -5
- package/dist/substrates/command-failure.d.ts +3 -3
- package/dist/substrates/command-failure.js +3 -3
- package/dist/substrates/desktop-session.js +2 -2
- package/dist/substrates/detached.d.ts +6 -6
- package/dist/substrates/detached.js +7 -7
- package/dist/substrates/e2b/cdp-probe.d.ts +9 -9
- package/dist/substrates/e2b/cdp-probe.js +14 -17
- package/dist/substrates/e2b/desktop-browser.d.ts +6 -6
- package/dist/substrates/e2b/desktop-browser.js +9 -9
- package/dist/substrates/e2b/desktop-cdp.d.ts +10 -10
- package/dist/substrates/e2b/desktop-cdp.js +9 -9
- package/dist/substrates/e2b/desktop-executor.d.ts +2 -2
- package/dist/substrates/e2b/desktop-executor.js +13 -13
- package/dist/substrates/e2b/desktop-geometry.d.ts +4 -4
- package/dist/substrates/e2b/desktop-geometry.js +8 -8
- package/dist/substrates/e2b/desktop-media.d.ts +4 -4
- package/dist/substrates/e2b/desktop-media.js +1 -1
- package/dist/substrates/e2b/desktop-screenshot-cleanup.d.ts +3 -3
- package/dist/substrates/e2b/desktop-screenshot-cleanup.js +3 -3
- package/dist/substrates/e2b/lifetime.js +1 -1
- package/dist/substrates/e2b/sandbox.d.ts +4 -4
- package/dist/substrates/e2b/sandbox.js +2 -2
- package/dist/substrates/e2b/sdk.d.ts +12 -12
- package/dist/substrates/e2b/sdk.js +7 -7
- package/dist/substrates/local/runtime-config.d.ts +4 -4
- package/dist/substrates/local/runtime-config.js +4 -4
- package/dist/tui/actions.d.ts +1 -1
- package/dist/tui/actions.js +13 -13
- package/dist/tui/contract.d.ts +23 -23
- package/dist/tui/contract.js +11 -11
- package/dist/tui/launch.d.ts +7 -7
- package/dist/tui/launch.js +36 -31
- package/dist/tui/project.js +5 -5
- package/dist/tui-app.js +139 -139
- package/dist/verify/actor.d.ts +8 -8
- package/dist/verify/actor.js +36 -36
- package/dist/verify/artifacts.d.ts +2 -2
- package/dist/verify/artifacts.js +3 -3
- package/dist/verify/context-growth.d.ts +9 -0
- package/dist/verify/context-growth.js +62 -0
- package/dist/verify/costs.d.ts +6 -6
- package/dist/verify/costs.js +8 -8
- package/dist/verify/shared-world-concurrent.d.ts +2 -2
- package/dist/verify/shared-world-concurrent.js +79 -76
- package/dist/verify/shared-world.d.ts +2 -2
- package/dist/verify/shared-world.js +16 -16
- package/dist/verify/subject.d.ts +5 -5
- package/dist/verify/subject.js +19 -19
- package/dist/verify/verify.js +94 -44
- package/docs/README.md +25 -32
- package/docs/architecture/actor-contract.md +60 -91
- package/docs/architecture/browser-control.md +1 -1
- package/docs/architecture/desktop-sessions.md +7 -7
- package/docs/architecture/external-public-shared-world.md +68 -65
- package/docs/architecture/github-feedback-loop.md +2 -5
- package/docs/architecture/guest-desktop.md +2 -2
- package/docs/architecture/observer.md +34 -34
- package/docs/architecture/restricted-codex-analysis.md +34 -28
- package/docs/architecture/serve.md +34 -37
- package/docs/architecture/state-driven-executor.md +55 -58
- package/docs/architecture/task-protocol-support.md +6 -6
- package/docs/architecture/terminal-product-route.md +70 -110
- package/docs/contracts/README.md +24 -0
- package/docs/contracts/adapter-admission.md +3 -3
- package/docs/contracts/adapter-fixtures.md +4 -7
- package/docs/contracts/core.md +1 -3
- package/docs/contracts/errors.md +62 -0
- package/docs/contracts/feedback.md +8 -9
- package/docs/contracts/policy.md +7 -12
- package/docs/contracts/run-bundle.md +42 -44
- package/docs/contracts/schemas.md +446 -368
- package/docs/contracts/study-analysis.md +7 -4
- package/docs/contracts/study-costs.md +28 -9
- package/docs/decisions/0001-run-bundle-is-the-source-of-truth.md +1 -1
- package/docs/decisions/0002-observer-is-one-self-contained-file.md +2 -2
- package/docs/decisions/0003-contained-paths-and-cleanup-authority.md +3 -3
- package/docs/principles/actor-fidelity.md +4 -4
- package/docs/principles/engineering.md +3 -3
- package/docs/principles/invariants-and-defaults.md +38 -38
- package/docs/principles/self-driving-harness.md +1 -5
- package/docs/principles/three-roles.md +1 -1
- package/docs/product/automatic-analysis.md +7 -7
- package/examples/README.md +1 -1
- package/examples/participant/README.md +5 -5
- package/examples/participant/run.mjs +11 -10
- package/examples/scorer/README.md +3 -3
- package/examples/scorer/run.mjs +11 -12
- package/examples/scorer/scorer.mjs +3 -3
- package/package.json +16 -17
- package/skills/humanish/SKILL.md +64 -60
- package/skills/humanish/agents/openai.yaml +1 -1
- package/AGENTS.md +0 -99
- package/CONTRIBUTING.md +0 -148
- package/dist/actors/codex/qualified-versions.d.ts +0 -72
- package/dist/actors/codex/qualified-versions.js +0 -132
- package/dist/cli/commands/lab-format.d.ts +0 -8
- package/dist/cli/commands/lab-route-run.d.ts +0 -19
- package/dist/cli/commands/lab-route-scripted.d.ts +0 -17
- package/dist/cli/commands/lab-route-terminal.d.ts +0 -17
- package/dist/cli/commands/lab-run.d.ts +0 -9
- package/dist/cli/commands/lab.d.ts +0 -3
- package/dist/cli/commands/lab.js +0 -199
- package/dist/cli/renamed-options.d.ts +0 -11
- package/dist/cli/renamed-options.js +0 -18
- package/dist/lab/composition-rules.d.ts +0 -7
- package/dist/lab/config.d.ts +0 -7
- package/dist/lab/discover.d.ts +0 -65
- package/dist/lab/init-templates.js +0 -416
- package/dist/lab/keys.d.ts +0 -2
- package/dist/lab/parse/comms.d.ts +0 -12
- package/dist/lab/parse/execution.d.ts +0 -19
- package/dist/lab/parse/subject-state.d.ts +0 -30
- package/dist/lab/plan.d.ts +0 -19
- package/dist/lab/plan.js +0 -132
- package/dist/lab/preflight-probes.d.ts +0 -3
- package/dist/lab/preflight-result.d.ts +0 -7
- package/dist/lab/preflight.d.ts +0 -92
- package/dist/lab/route-inputs.d.ts +0 -28
- package/dist/lab/run-lab-options.d.ts +0 -28
- package/dist/lab/warnings.d.ts +0 -2
- package/dist/observer/static.d.ts +0 -39
- package/dist/observer/static.js +0 -369
- package/dist/run-lab.d.ts +0 -112
- package/docs/architecture/comms-inbox.md +0 -122
- package/docs/architecture/desktop-recording.md +0 -80
- package/docs/architecture/local-browser-runtime.md +0 -178
- package/docs/architecture/observer-review.md +0 -144
- package/docs/architecture/participant-media.md +0 -90
- package/docs/architecture/project-layout.md +0 -62
- package/docs/architecture/real-email-receiving.md +0 -136
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/assets/humanish-observer-hero.png +0 -0
- package/docs/goals/current.md +0 -207
- package/docs/product/lobby-trivia-3player-external-public.md +0 -77
- package/docs/product/open-source-install-experience.md +0 -240
- package/docs/ramp/README.md +0 -295
- package/docs/release/open-source-readiness.md +0 -222
- package/docs/release/public-readiness-standard.md +0 -210
- package/docs/roadmap/world-class-open-source-v0.md +0 -311
- /package/dist/{lab → study}/init-paths.d.ts +0 -0
- /package/dist/{lab → study}/init-paths.js +0 -0
- /package/dist/{lab → study}/init-plan.d.ts +0 -0
- /package/dist/{lab → study}/init-plan.js +0 -0
- /package/dist/{lab → study}/participant-assignment.d.ts +0 -0
- /package/dist/{lab → study}/participant-assignment.js +0 -0
- /package/dist/{lab → study}/persona.d.ts +0 -0
- /package/dist/{lab → study}/persona.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ParticipantIds } from "./participant-records.js";
|
|
2
2
|
export declare const SHARED_WORLD_SCHEMA = "humanish.shared-world.v1";
|
|
3
|
-
/** The shared service-plane provenance for a shared-world run
|
|
3
|
+
/** The shared service-plane provenance for a shared-world run: single commit + a
|
|
4
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). */
|
|
@@ -11,13 +11,13 @@ export interface SharedWorldPlane {
|
|
|
11
11
|
/** Declared env names provisioned for the shared plane (values never surface). */
|
|
12
12
|
envNames: string[];
|
|
13
13
|
/**
|
|
14
|
-
* Concurrent route only
|
|
15
|
-
* (the first-class provisioned-subject target every actor drove
|
|
14
|
+
* Concurrent route only: sha256-16 of the harness-minted `getHost` URL's origin
|
|
15
|
+
* (the first-class provisioned-subject target every actor drove). A digest replaces the
|
|
16
16
|
* raw URL: a getHost URL embeds the (live) sandbox id and matches the publish-safety e2b-URL
|
|
17
|
-
* redaction, so
|
|
18
|
-
* bundle (the raw tokenless URL is surfaced only on the ephemeral
|
|
19
|
-
* confirms the URL is tokenless (no authKey,
|
|
20
|
-
* actor drove this host by digest equality. Absent on the sequential route.
|
|
17
|
+
* redaction, so, like the stream URL and sandbox ids, it never lands raw in a published
|
|
18
|
+
* bundle (the raw tokenless URL is surfaced only on the ephemeral study result). The orchestrator
|
|
19
|
+
* confirms the URL is tokenless (no authKey, so no secret reaches the bundle) before digesting.
|
|
20
|
+
* verify proves every actor drove this host by digest equality. Absent on the sequential route.
|
|
21
21
|
*/
|
|
22
22
|
hostDigest?: string;
|
|
23
23
|
/**
|
|
@@ -30,17 +30,17 @@ export interface SharedWorldPlane {
|
|
|
30
30
|
*/
|
|
31
31
|
exposure?: "synthetic";
|
|
32
32
|
/**
|
|
33
|
-
* External-public plane class only
|
|
33
|
+
* External-public plane class only: sha256-16 of the observed origin the participants
|
|
34
34
|
* converged on. It is the counterpart of hostDigest with a weaker, disclosed claim: the harness only
|
|
35
|
-
* observes that each
|
|
36
|
-
*
|
|
37
|
-
* (that
|
|
38
|
-
* origin, not harness control of the plane. A
|
|
39
|
-
* hostDigest hygiene). Absent on getHost.
|
|
35
|
+
* observes that each participant reached this origin and never minted it. It is derived from what
|
|
36
|
+
* the participants actually reached; the declared appUrl does not feed it. verify proves every
|
|
37
|
+
* laneWindow.routeHostDigest (that participant's CDP-observed final URL origin) equals it, which
|
|
38
|
+
* shows cross-participant convergence on one observed origin, not harness control of the plane. A
|
|
39
|
+
* digest, not the raw origin (kept consistent with 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
44
|
* recorded for reference/evidence only. It is never asserted equal to publicOriginDigest: a normal
|
|
45
45
|
* cross-origin redirect (apex->www, http->https) makes the observed origin differ from the declared
|
|
46
46
|
* one, which is expected. Operator ownership rests on the subject.publicTarget.authorized attestation
|
|
@@ -49,7 +49,7 @@ export interface SharedWorldPlane {
|
|
|
49
49
|
declaredOriginDigest?: string;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
52
|
-
* Concurrent shape
|
|
52
|
+
* Concurrent shape: one actor's harness-clocked activity window against the one
|
|
53
53
|
* shared plane. Overlapping windows mechanically prove ≥2 personas were active simultaneously.
|
|
54
54
|
* `laneWindows` and `stateSeries` are independent series. There is deliberately no per-delta→actor
|
|
55
55
|
* field, because under concurrency the evidence cannot say which actor caused a state change.
|
|
@@ -68,9 +68,9 @@ export interface SharedWorldParticipantWindow {
|
|
|
68
68
|
endedAt: number;
|
|
69
69
|
/** The actor's terminal session verdict (per-persona). */
|
|
70
70
|
verdict: string;
|
|
71
|
-
/** sha256-16 of the origin of the getHost
|
|
72
|
-
* plane.hostDigest, so the actor drove exactly the harness-minted host
|
|
73
|
-
*
|
|
71
|
+
/** sha256-16 of the origin of the getHost participant URL this actor drove. verify confirms it
|
|
72
|
+
* equals plane.hostDigest, so the actor drove exactly the harness-minted host. A digest, not the
|
|
73
|
+
* 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). */
|
|
76
76
|
commit?: string;
|
|
@@ -109,19 +109,19 @@ export declare function sharedWorldParticipantKeys(ids: ParticipantIds, particip
|
|
|
109
109
|
readonly caseGroup?: string;
|
|
110
110
|
}): Pick<SharedWorldOutcome, "roleId" | "actorType" | "surface" | "caseGroup" | "simId" | "streamId">;
|
|
111
111
|
/** A timeline checkpoint: a read-only digest probe of the shared plane at one moment. Persisted
|
|
112
|
-
*
|
|
112
|
+
* digest-only: `digest` is sha256-16(scrub+redact(stdout)); no raw value ever lands. */
|
|
113
113
|
export interface SharedWorldCheckpoint {
|
|
114
114
|
kind: "checkpoint";
|
|
115
115
|
/** "cp-baseline" for the baseline snapshot; "cp-after-<roleId>" after each role's turn. */
|
|
116
116
|
name: string;
|
|
117
117
|
/** sha256-16 of the (scrubbed, redacted) combined probe output at this snapshot. */
|
|
118
118
|
digest: string;
|
|
119
|
-
/** True when this snapshot's digest differs from the previous checkpoint's
|
|
119
|
+
/** True when this snapshot's digest differs from the previous checkpoint's, meaning the observed
|
|
120
120
|
* state changed across the intervening turn (the delta is attributed to the whole turn). */
|
|
121
121
|
deltaFromPrev: boolean;
|
|
122
122
|
}
|
|
123
|
-
/** A timeline turn: one
|
|
124
|
-
* provenance it observed (identical across turns by construction
|
|
123
|
+
/** A timeline turn: one participant's session against the shared plane. Carries the plane
|
|
124
|
+
* provenance it observed (identical across turns by construction: the single-plane proof). */
|
|
125
125
|
interface SharedWorldTurn {
|
|
126
126
|
kind: "turn";
|
|
127
127
|
roleId: string;
|
|
@@ -135,8 +135,8 @@ interface SharedWorldTurn {
|
|
|
135
135
|
seedDigest: string;
|
|
136
136
|
}
|
|
137
137
|
type SharedWorldTimelineEntry = SharedWorldCheckpoint | SharedWorldTurn;
|
|
138
|
-
/** Declared
|
|
139
|
-
* The executed timeline plus this ordered tail must account for every declared sim/stream. */
|
|
138
|
+
/** Declared participants that were never started after one executed sequential role stopped the
|
|
139
|
+
* run. The executed timeline plus this ordered tail must account for every declared sim/stream. */
|
|
140
140
|
interface SharedWorldSkippedTail {
|
|
141
141
|
afterRoleId: string;
|
|
142
142
|
roles: Array<{
|
|
@@ -156,10 +156,10 @@ interface SharedWorldSkippedTail {
|
|
|
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
|
-
* - Concurrent (`topologyMode: "concurrent"
|
|
159
|
+
* - Concurrent (`topologyMode: "concurrent"`): `laneWindows` + `stateSeries` +
|
|
160
160
|
* `outcomes`; limits `concurrent` etc. No `timeline`.
|
|
161
161
|
*
|
|
162
|
-
* Additive + optional on `humanish.run-bundle.v1
|
|
162
|
+
* Additive + optional on `humanish.run-bundle.v1`: absent on every non-shared-world bundle.
|
|
163
163
|
* The mandatory `attributionLimits` are verify-enforced (fail closed on a missing required or a
|
|
164
164
|
* present forbidden limit).
|
|
165
165
|
*/
|
|
@@ -169,26 +169,27 @@ export interface SharedWorldEvidence {
|
|
|
169
169
|
/** The substrate discriminator. Branched on first by sharedWorldEvidenceFindings. */
|
|
170
170
|
topologyMode: "sequential" | "concurrent";
|
|
171
171
|
/**
|
|
172
|
-
* Concurrent route only
|
|
173
|
-
* "provisioned-getHost" plane (a clone/local-tree subject served + getHost-exposed in-sandbox
|
|
172
|
+
* Concurrent route only: the plane-class discriminator. Absent == the historical
|
|
173
|
+
* "provisioned-getHost" plane (a clone/local-tree subject served + getHost-exposed in-sandbox; the
|
|
174
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
176
|
* plane (no getHost/clone/seed; the operator attests it and the harness does not control it; no authoritative
|
|
177
|
-
* shared-state proof
|
|
177
|
+
* shared-state proof: concurrency evidenced by temporal co-occupancy + observed lobby convergence).
|
|
178
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 declared number of
|
|
182
|
+
/** The declared number of participants. */
|
|
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
|
-
*
|
|
189
|
-
* `/lobby/CODE` path every
|
|
190
|
-
* shared world" proof, observation-derived and needing no subject change. Digest-only (the
|
|
191
|
-
* 6-char lobby code and full URLs are runtime-only and never land). Absent when
|
|
188
|
+
* External-public plane class only (optional-but-strong): sha256-16 of the shared
|
|
189
|
+
* `/lobby/CODE` path every participant's CDP-observed URL converged on: the concrete "they were
|
|
190
|
+
* in one shared world" proof, observation-derived and needing no subject change. Digest-only (the
|
|
191
|
+
* raw 6-char lobby code and full URLs are runtime-only and never land). Absent when participants
|
|
192
|
+
* did not converge.
|
|
192
193
|
*/
|
|
193
194
|
lobbyConvergenceDigest?: string;
|
|
194
195
|
/** The role ids that actually took a turn, in declared order. */
|
|
@@ -210,8 +211,8 @@ interface ParticipantWindow {
|
|
|
210
211
|
}
|
|
211
212
|
/**
|
|
212
213
|
* What a shared-world run shows about concurrency, as verify's pass gate and the judge both read
|
|
213
|
-
* it: whether two or more
|
|
214
|
-
* provisioned plane), whether the state changed at or after the first overlap started.
|
|
214
|
+
* it: whether two or more participants were live at once, and, when the plane keeps a state series
|
|
215
|
+
* (the provisioned plane), whether the state changed at or after the first overlap started.
|
|
215
216
|
*/
|
|
216
217
|
export declare function concurrencyFacts(windows: readonly ParticipantWindow[], stateSeries: readonly SharedWorldStateSnapshot[] | undefined): {
|
|
217
218
|
overlap: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The sharedWorld block of run.json (humanish.shared-world.v1): the one shared plane, each
|
|
2
|
-
// window, state snapshots and the interleaved timeline of checkpoints and turns.
|
|
1
|
+
// The sharedWorld block of run.json (humanish.shared-world.v1): the one shared plane, each
|
|
2
|
+
// participant's window, state snapshots and the interleaved timeline of checkpoints and turns.
|
|
3
3
|
export const SHARED_WORLD_SCHEMA = "humanish.shared-world.v1";
|
|
4
4
|
/**
|
|
5
5
|
* The fields a window and an outcome start with, in the saved order: the participant id saved as
|
|
@@ -30,8 +30,8 @@ function overlapStarts(windows) {
|
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* What a shared-world run shows about concurrency, as verify's pass gate and the judge both read
|
|
33
|
-
* it: whether two or more
|
|
34
|
-
* provisioned plane), whether the state changed at or after the first overlap started.
|
|
33
|
+
* it: whether two or more participants were live at once, and, when the plane keeps a state series
|
|
34
|
+
* (the provisioned plane), whether the state changed at or after the first overlap started.
|
|
35
35
|
*/
|
|
36
36
|
export function concurrencyFacts(windows, stateSeries) {
|
|
37
37
|
const starts = overlapStarts(windows);
|
|
@@ -18,7 +18,7 @@ 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 shape guard for the shared-world evidence block
|
|
21
|
+
* Tolerant shape guard for the shared-world evidence block. Validates required fields +
|
|
22
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).
|
|
@@ -4,18 +4,18 @@ import { isNonNegativeSafeInteger, isRecord } from "./type-guards.js";
|
|
|
4
4
|
// The promptDigest convention: sha256 hex, first 16 chars. A "seeded" record without a real
|
|
5
5
|
// digest cannot pin "same recipe" across bundles, so verify treats it as a hollow claim.
|
|
6
6
|
export const COMMAND_DIGEST_PATTERN = /^[0-9a-f]{16}$/;
|
|
7
|
-
// Env var name shape (mirrors ENV_NAME_PATTERN in src/
|
|
7
|
+
// Env var name shape (mirrors ENV_NAME_PATTERN in src/study/parse/values.ts). externalEnvNames
|
|
8
8
|
// must hold names only: a value sneaking into the list trips this check (a free secret tripwire).
|
|
9
9
|
export const SUBJECT_ENV_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
10
10
|
// Sequential: the three disclosures a sequential shared-world bundle must pin (verify fails closed
|
|
11
|
-
// if any is absent
|
|
11
|
+
// if any is absent, because omission overclaims): sequential turns only, no concurrency/races handled, and
|
|
12
12
|
// a checkpoint delta is attributed to the turn it followed, never a specific action (correlation).
|
|
13
13
|
export const MANDATORY_ATTRIBUTION_LIMITS = [
|
|
14
14
|
"sequential-only",
|
|
15
15
|
"no-concurrent-races",
|
|
16
16
|
"delta-attributed-to-turn-not-action",
|
|
17
17
|
];
|
|
18
|
-
// A shared-world checkpoint record persists
|
|
18
|
+
// A shared-world checkpoint record persists digest-only: exactly these keys, nothing value-shaped.
|
|
19
19
|
export const SHARED_WORLD_CHECKPOINT_KEYS = new Set(["kind", "name", "digest", "deltaFromPrev"]);
|
|
20
20
|
// A concurrent stateSeries record is digest-only too: it permits a numeric timestamp + the
|
|
21
21
|
// sha256-16 digest; any other key is a value-shaped leak / a smuggled per-delta→actor field.
|
|
@@ -30,7 +30,7 @@ export function planeProvenanceFindings(items, plane, labels) {
|
|
|
30
30
|
const findings = [];
|
|
31
31
|
const keys = new Set(items.map((item) => `${text(item.commit)}::${text(item.seedDigest)}`));
|
|
32
32
|
if (keys.size > 1) {
|
|
33
|
-
findings.push(`${labels.items} reference
|
|
33
|
+
findings.push(`${labels.items} reference different plane provenance (commit or seedDigest), but a ${labels.run} run uses one plane`);
|
|
34
34
|
}
|
|
35
35
|
if (!isRecord(plane))
|
|
36
36
|
return findings;
|
|
@@ -63,14 +63,14 @@ export function sharedWorldCommonFindings(bundle, sw) {
|
|
|
63
63
|
for (const name of plane.envNames) {
|
|
64
64
|
if (typeof name !== "string" || !SUBJECT_ENV_NAME_PATTERN.test(name)) {
|
|
65
65
|
// Never echoes the entry: a malformed entry may be a value.
|
|
66
|
-
findings.push("sharedWorld.plane.envNames
|
|
66
|
+
findings.push("sharedWorld.plane.envNames has an entry that is not an environment variable name; evidence may hold names only, never values");
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
return findings;
|
|
71
71
|
}
|
|
72
72
|
/**
|
|
73
|
-
* Tolerant shape guard for the shared-world evidence block
|
|
73
|
+
* Tolerant shape guard for the shared-world evidence block. Validates required fields +
|
|
74
74
|
* types and tolerates extra keys (additive): the strict value-shape/timeline checks are
|
|
75
75
|
* sharedWorldEvidenceFindings' job (an injected value-shaped checkpoint field must pass the shape
|
|
76
76
|
* guard so verify can catch it fail-closed, not silently bounce off isRunBundle).
|
|
@@ -110,7 +110,7 @@ export function isSharedWorldEvidence(value) {
|
|
|
110
110
|
value.attributionLimits.every((limit) => typeof limit === "string")))
|
|
111
111
|
return false;
|
|
112
112
|
// Tolerant: validate the type of each present field only (the coherence + topologyMode dispatch
|
|
113
|
-
// are the job of sharedWorldEvidenceFindings
|
|
113
|
+
// are the job of sharedWorldEvidenceFindings; an injected value-shaped field must pass this
|
|
114
114
|
// guard so verify catches it fail-closed). A bundle must carry at least one of the two shapes.
|
|
115
115
|
if (value.sequence !== undefined &&
|
|
116
116
|
!(Array.isArray(value.sequence) && value.sequence.every((id) => typeof id === "string")))
|
package/dist/run/stats.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { type CostTotals, type CostRow } from "./costs.js";
|
|
2
|
-
declare const STATS_SCHEMA = "humanish.stats.
|
|
2
|
+
declare const STATS_SCHEMA = "humanish.stats.v2";
|
|
3
3
|
interface StatsParticipants {
|
|
4
4
|
total: number;
|
|
5
5
|
reachedGoal: number;
|
|
6
6
|
reportedFriction: number;
|
|
7
7
|
}
|
|
8
|
-
interface
|
|
9
|
-
|
|
8
|
+
interface StatsStudyRow {
|
|
9
|
+
/** The study's `id`. */
|
|
10
|
+
study: string;
|
|
10
11
|
runs: number;
|
|
11
12
|
live: number;
|
|
12
13
|
dryRun: number;
|
|
@@ -40,7 +41,8 @@ export interface StatsResult {
|
|
|
40
41
|
ok: true;
|
|
41
42
|
cwd: string;
|
|
42
43
|
since?: string;
|
|
43
|
-
|
|
44
|
+
/** The study the stats are limited to, when one was given. */
|
|
45
|
+
study?: string;
|
|
44
46
|
totals: {
|
|
45
47
|
runs: number;
|
|
46
48
|
live: number;
|
|
@@ -53,11 +55,11 @@ export interface StatsResult {
|
|
|
53
55
|
verdicts: Record<string, number>;
|
|
54
56
|
costs: CostTotals;
|
|
55
57
|
};
|
|
56
|
-
|
|
58
|
+
studies: StatsStudyRow[];
|
|
57
59
|
days: StatsDayRow[];
|
|
58
60
|
/** Same selected runs; individual accounting gaps are inspectable without reading private evidence. */
|
|
59
61
|
costsByRun: CostRow[];
|
|
60
|
-
/** Directories that could not be read, by name
|
|
62
|
+
/** Directories that could not be read, by name: surfaced, never silently dropped. */
|
|
61
63
|
unreadable: string[];
|
|
62
64
|
note: string;
|
|
63
65
|
}
|
|
@@ -65,7 +67,7 @@ export interface StatsOptions {
|
|
|
65
67
|
/** ISO date or datetime; runs that started before it are excluded. */
|
|
66
68
|
since?: string;
|
|
67
69
|
/** Lab id; runs from other labs are excluded. */
|
|
68
|
-
|
|
70
|
+
study?: string;
|
|
69
71
|
nowMs?: number;
|
|
70
72
|
}
|
|
71
73
|
export interface StatsFailure {
|
|
@@ -78,5 +80,9 @@ export interface StatsFailure {
|
|
|
78
80
|
};
|
|
79
81
|
}
|
|
80
82
|
export declare function computeStats(cwdInput: string, options?: StatsOptions): Promise<StatsResult | StatsFailure>;
|
|
81
|
-
|
|
83
|
+
/** Human output; a failure is an error the CLI prints on stderr (HumanOutput in src/cli/io.ts). */
|
|
84
|
+
export declare function formatStatsHuman(result: StatsResult): string;
|
|
85
|
+
export declare function formatStatsHuman(result: StatsResult | StatsFailure): string | {
|
|
86
|
+
error: StatsFailure["error"];
|
|
87
|
+
};
|
|
82
88
|
export {};
|
package/dist/run/stats.js
CHANGED
|
@@ -5,12 +5,10 @@ import path from "node:path";
|
|
|
5
5
|
import { readRunIndex } from "./run-index.js";
|
|
6
6
|
import { addCostTotals, emptyCostTotals, readCostTotals, } from "./costs.js";
|
|
7
7
|
import { round6 } from "./pricing.js";
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"Analysis is attributed to its run's start date, including later reruns. " +
|
|
13
|
-
"JSON estimatedSpendUsd and medianCostUsd retain their participant/desktop-only meaning; costs includes analysis.";
|
|
8
|
+
import { plural } from "./text.js";
|
|
9
|
+
const STATS_SCHEMA = "humanish.stats.v2";
|
|
10
|
+
// docs/contracts/study-costs.md holds the accounting rules this sentence summarizes.
|
|
11
|
+
const STATS_NOTE = "Dollar figures are estimates from humanish's rate table, never provider charges, and a cost humanish does not know is left out of every total.";
|
|
14
12
|
function median(values) {
|
|
15
13
|
if (values.length === 0)
|
|
16
14
|
return undefined;
|
|
@@ -28,15 +26,26 @@ function addParticipants(into, entry) {
|
|
|
28
26
|
into.reachedGoal += entry.participants.reachedGoal;
|
|
29
27
|
into.reportedFriction += entry.participants.reportedFriction ?? 0;
|
|
30
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* A run's participant and desktop estimate: its recorded figure, or $0 for a dry run that records
|
|
31
|
+
* none, since a dry run makes no model request and creates no desktop. Undefined when the cost is
|
|
32
|
+
* unknown, including a dry run that records an unknown (null) figure.
|
|
33
|
+
*/
|
|
34
|
+
function runEstimateUsd(entry) {
|
|
35
|
+
const usd = entry.estimatedCostUsd;
|
|
36
|
+
if (typeof usd === "number" && Number.isFinite(usd) && usd >= 0)
|
|
37
|
+
return usd;
|
|
38
|
+
return usd === undefined && entry.mode === "dry-run" ? 0 : undefined;
|
|
39
|
+
}
|
|
31
40
|
function entryTime(entry) {
|
|
32
41
|
return entry.startedAt ?? entry.completedAt ?? entry.updatedAt;
|
|
33
42
|
}
|
|
34
|
-
function
|
|
35
|
-
const
|
|
36
|
-
let row =
|
|
43
|
+
function addToStudyRow(studies, entry, runUsd, costs) {
|
|
44
|
+
const studyId = entry.study?.id ?? "(no study)";
|
|
45
|
+
let row = studies.get(studyId);
|
|
37
46
|
if (row === undefined) {
|
|
38
47
|
row = {
|
|
39
|
-
|
|
48
|
+
study: studyId,
|
|
40
49
|
runs: 0,
|
|
41
50
|
live: 0,
|
|
42
51
|
dryRun: 0,
|
|
@@ -50,7 +59,7 @@ function addToLabRow(labs, entry, priced, costs) {
|
|
|
50
59
|
costs: emptyCostTotals(),
|
|
51
60
|
runCosts: [],
|
|
52
61
|
};
|
|
53
|
-
|
|
62
|
+
studies.set(studyId, row);
|
|
54
63
|
}
|
|
55
64
|
row.runs += 1;
|
|
56
65
|
if (entry.mode === "live")
|
|
@@ -64,14 +73,14 @@ function addToLabRow(labs, entry, priced, costs) {
|
|
|
64
73
|
}
|
|
65
74
|
if (entry.mode === "live" && entry.durationMs !== undefined)
|
|
66
75
|
row.durations.push(entry.durationMs);
|
|
67
|
-
if (
|
|
68
|
-
row.runCosts.push(entry.estimatedCostUsd);
|
|
69
|
-
else
|
|
76
|
+
if (runUsd === undefined)
|
|
70
77
|
row.unpricedRuns += 1;
|
|
78
|
+
else
|
|
79
|
+
row.runCosts.push(runUsd);
|
|
71
80
|
addParticipants(row.participants, entry);
|
|
72
81
|
addCostTotals(row.costs, costs);
|
|
73
82
|
}
|
|
74
|
-
function addToDayRow(days, entry,
|
|
83
|
+
function addToDayRow(days, entry, runUsd, costs) {
|
|
75
84
|
const at = entryTime(entry);
|
|
76
85
|
const day = at === undefined ? "(undated)" : at.slice(0, 10);
|
|
77
86
|
let dayRow = days.get(day);
|
|
@@ -89,10 +98,10 @@ function addToDayRow(days, entry, priced, costs) {
|
|
|
89
98
|
dayRow.runs += 1;
|
|
90
99
|
if (entry.mode === "live")
|
|
91
100
|
dayRow.live += 1;
|
|
92
|
-
if (
|
|
93
|
-
dayRow.estimatedSpendUsd += entry.estimatedCostUsd;
|
|
94
|
-
else
|
|
101
|
+
if (runUsd === undefined)
|
|
95
102
|
dayRow.unpricedRuns += 1;
|
|
103
|
+
else
|
|
104
|
+
dayRow.estimatedSpendUsd += runUsd;
|
|
96
105
|
addCostTotals(dayRow.costs, costs);
|
|
97
106
|
}
|
|
98
107
|
export async function computeStats(cwdInput, options = {}) {
|
|
@@ -114,7 +123,7 @@ export async function computeStats(cwdInput, options = {}) {
|
|
|
114
123
|
}
|
|
115
124
|
const index = await readRunIndex(cwd, options.nowMs === undefined ? {} : { nowMs: options.nowMs });
|
|
116
125
|
// Corrupt source metadata must not hide separately retained paid analysis receipts.
|
|
117
|
-
// These directories cannot be attributed to a
|
|
126
|
+
// These directories cannot be attributed to a study or date, so scoped filters exclude them.
|
|
118
127
|
const indexedIds = new Set(index.runs.map((entry) => entry.runId));
|
|
119
128
|
const entries = [
|
|
120
129
|
...index.runs,
|
|
@@ -127,7 +136,7 @@ export async function computeStats(cwdInput, options = {}) {
|
|
|
127
136
|
})),
|
|
128
137
|
];
|
|
129
138
|
const selected = entries.filter((entry) => {
|
|
130
|
-
if (options.
|
|
139
|
+
if (options.study !== undefined && entry.study?.id !== options.study)
|
|
131
140
|
return false;
|
|
132
141
|
if (sinceMs !== undefined) {
|
|
133
142
|
const at = entryTime(entry);
|
|
@@ -150,7 +159,7 @@ export async function computeStats(cwdInput, options = {}) {
|
|
|
150
159
|
verdicts: {},
|
|
151
160
|
costs: emptyCostTotals(),
|
|
152
161
|
};
|
|
153
|
-
const
|
|
162
|
+
const studies = new Map();
|
|
154
163
|
const days = new Map();
|
|
155
164
|
const costsByRun = [];
|
|
156
165
|
for (const entry of selected) {
|
|
@@ -164,20 +173,18 @@ export async function computeStats(cwdInput, options = {}) {
|
|
|
164
173
|
totals.dryRun += 1;
|
|
165
174
|
if (entry.liveness === "running")
|
|
166
175
|
totals.running += 1;
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
entry.estimatedCostUsd >= 0;
|
|
170
|
-
if (priced)
|
|
171
|
-
totals.estimatedSpendUsd += entry.estimatedCostUsd;
|
|
172
|
-
else
|
|
176
|
+
const runUsd = runEstimateUsd(entry);
|
|
177
|
+
if (runUsd === undefined)
|
|
173
178
|
totals.unpricedRuns += 1;
|
|
179
|
+
else
|
|
180
|
+
totals.estimatedSpendUsd += runUsd;
|
|
174
181
|
addParticipants(totals.participants, entry);
|
|
175
182
|
if (entry.verdict !== undefined)
|
|
176
183
|
totals.verdicts[entry.verdict] = (totals.verdicts[entry.verdict] ?? 0) + 1;
|
|
177
|
-
|
|
178
|
-
addToDayRow(days, entry,
|
|
184
|
+
addToStudyRow(studies, entry, runUsd, accounting.costs);
|
|
185
|
+
addToDayRow(days, entry, runUsd, accounting.costs);
|
|
179
186
|
}
|
|
180
|
-
const
|
|
187
|
+
const studyRows = [...studies.values()]
|
|
181
188
|
.map(({ durations, runCosts, ...row }) => ({
|
|
182
189
|
...row,
|
|
183
190
|
...(row.judged === 0 ? {} : { passRate: round6(row.passed / row.judged) }),
|
|
@@ -186,15 +193,15 @@ export async function computeStats(cwdInput, options = {}) {
|
|
|
186
193
|
...(runCosts.length === 0 ? {} : { medianCostUsd: round6(median(runCosts)) }),
|
|
187
194
|
costSamples: runCosts.length,
|
|
188
195
|
}))
|
|
189
|
-
.sort((a, b) => b.runs - a.runs || a.
|
|
196
|
+
.sort((a, b) => b.runs - a.runs || a.study.localeCompare(b.study));
|
|
190
197
|
return {
|
|
191
198
|
schema: STATS_SCHEMA,
|
|
192
199
|
ok: true,
|
|
193
200
|
cwd,
|
|
194
201
|
...(options.since === undefined ? {} : { since: options.since }),
|
|
195
|
-
...(options.
|
|
202
|
+
...(options.study === undefined ? {} : { study: options.study }),
|
|
196
203
|
totals: { ...totals, estimatedSpendUsd: round6(totals.estimatedSpendUsd) },
|
|
197
|
-
|
|
204
|
+
studies: studyRows,
|
|
198
205
|
days: [...days.values()]
|
|
199
206
|
.map((row) => ({ ...row, estimatedSpendUsd: round6(row.estimatedSpendUsd) }))
|
|
200
207
|
.sort((a, b) => a.day.localeCompare(b.day)),
|
|
@@ -212,47 +219,98 @@ function knownMoney(value) {
|
|
|
212
219
|
function minutes(ms) {
|
|
213
220
|
return `${(ms / 60_000).toFixed(1)}m`;
|
|
214
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Whether every selected run is a dry run whose accounting is a complete $0: no recorded figure,
|
|
224
|
+
* no incomplete estimate and no analysis attempt. Only then does the one-line report hold.
|
|
225
|
+
*/
|
|
226
|
+
function onlyFreeDryRuns(t) {
|
|
227
|
+
return (t.runs > 0 &&
|
|
228
|
+
t.runs === t.dryRun &&
|
|
229
|
+
t.costs.estimatedTotalUsd === 0 &&
|
|
230
|
+
t.costs.incompleteRunEstimates === 0 &&
|
|
231
|
+
t.costs.analysisAttempts === 0);
|
|
232
|
+
}
|
|
233
|
+
/** The run counts, with dry runs on their own line. */
|
|
234
|
+
function runCountLines(t) {
|
|
235
|
+
if (t.runs === 0)
|
|
236
|
+
return ["no runs yet; start one with humanish run first-run"];
|
|
237
|
+
if (onlyFreeDryRuns(t))
|
|
238
|
+
return [`${plural(t.dryRun, "dry run")} ($0); no live runs yet`];
|
|
239
|
+
const running = t.running > 0 ? ` (${t.running} still running)` : "";
|
|
240
|
+
return [`live runs: ${t.live}${running}`, ...(t.dryRun > 0 ? [`dry runs: ${t.dryRun}`] : [])];
|
|
241
|
+
}
|
|
242
|
+
/** Spend, analysis, participants and verdicts across the selected live runs. */
|
|
243
|
+
function totalsLines(t) {
|
|
244
|
+
const c = t.costs;
|
|
245
|
+
const incomplete = c.incompleteRunEstimates > 0
|
|
246
|
+
? `; ${plural(c.incompleteRunEstimates, "run")} with incomplete accounting`
|
|
247
|
+
: "";
|
|
248
|
+
const unpriced = c.analysisUnpricedAttempts > 0 || c.analysisUnresolvedAttempts > 0
|
|
249
|
+
? `; ${c.analysisUnpricedAttempts} unpriced, ${c.analysisUnresolvedAttempts} unresolved`
|
|
250
|
+
: "";
|
|
251
|
+
const verdicts = Object.entries(t.verdicts).map(([verdict, count]) => `${verdict} ${count}`);
|
|
252
|
+
return [
|
|
253
|
+
`known estimated spend: ${knownMoney(c.estimatedTotalUsd)}`,
|
|
254
|
+
`participants and desktops: ${knownMoney(c.runEstimatedUsd)}${incomplete}`,
|
|
255
|
+
c.analysisAttempts === 0
|
|
256
|
+
? "analysis: none recorded"
|
|
257
|
+
: `analysis: ${knownMoney(c.analysisEstimatedUsd)} over ${plural(c.analysisAttempts, "recorded attempt")}${unpriced}`,
|
|
258
|
+
...(c.analysisHistoryUncertainRuns > 0
|
|
259
|
+
? [
|
|
260
|
+
`analysis history: ${plural(c.analysisHistoryUncertainRuns, "run")} missing or uncertain; --json lists each run`,
|
|
261
|
+
]
|
|
262
|
+
: []),
|
|
263
|
+
...(t.participants.total > 0
|
|
264
|
+
? [
|
|
265
|
+
`participants: ${t.participants.reachedGoal} of ${t.participants.total} reached the goal, ${t.participants.reportedFriction} reported friction`,
|
|
266
|
+
]
|
|
267
|
+
: []),
|
|
268
|
+
...(verdicts.length > 0 ? [`verdicts: ${verdicts.join(", ")}`] : []),
|
|
269
|
+
];
|
|
270
|
+
}
|
|
271
|
+
function dayLine(row) {
|
|
272
|
+
return `- ${row.day}: ${plural(row.runs, "run")}, ${row.live} live, known study spend ${knownMoney(row.costs.estimatedTotalUsd)}${unpricedTail(row.unpricedRuns, row.costs.analysisUnpricedAttempts)}`;
|
|
273
|
+
}
|
|
274
|
+
/** "; 2 unpriced runs, 1 unpriced analysis", or nothing when both are zero. */
|
|
275
|
+
function unpricedTail(runs, analyses) {
|
|
276
|
+
if (runs === 0 && analyses === 0)
|
|
277
|
+
return "";
|
|
278
|
+
return `; ${plural(runs, "unpriced run")}, ${plural(analyses, "unpriced analysis", "unpriced analyses")}`;
|
|
279
|
+
}
|
|
215
280
|
export function formatStatsHuman(result) {
|
|
216
281
|
if (!result.ok)
|
|
217
|
-
return
|
|
282
|
+
return { error: result.error };
|
|
218
283
|
const t = result.totals;
|
|
219
284
|
const scope = [
|
|
220
|
-
result.
|
|
285
|
+
result.study === undefined ? undefined : `study ${result.study}`,
|
|
221
286
|
result.since === undefined ? undefined : `since ${result.since}`,
|
|
222
287
|
].filter((part) => part !== undefined);
|
|
223
288
|
const lines = [
|
|
224
289
|
`humanish stats${scope.length === 0 ? "" : ` (${scope.join(", ")})`}`,
|
|
225
|
-
|
|
226
|
-
`known estimated spend: ${knownMoney(t.costs.estimatedTotalUsd)}`,
|
|
227
|
-
`participants + desktops: ${knownMoney(t.costs.runEstimatedUsd)}; ${t.costs.incompleteRunEstimates} run(s) with incomplete accounting`,
|
|
228
|
-
`analysis: ${knownMoney(t.costs.analysisEstimatedUsd)} over ${t.costs.analysisAttempts} recorded attempt(s); ${t.costs.analysisUnpricedAttempts} unpriced, ${t.costs.analysisUnresolvedAttempts} unresolved`,
|
|
229
|
-
`analysis history: ${t.costs.analysisHistoryUncertainRuns} run(s) missing or uncertain; use --json for per-run accounting`,
|
|
230
|
-
`participants: ${t.participants.reachedGoal}/${t.participants.total} recorded goal completions, ${t.participants.reportedFriction} reported friction`,
|
|
231
|
-
`verdicts: ${Object.entries(t.verdicts)
|
|
232
|
-
.map(([verdict, count]) => `${verdict} ${count}`)
|
|
233
|
-
.join(", ") || "none recorded"}`,
|
|
290
|
+
...runCountLines(t),
|
|
234
291
|
];
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
292
|
+
// Free dry runs alone have no spend, outcome or duration to report. Anything else, an unreadable
|
|
293
|
+
// directory or a dry run that records a cost included, gets the full report.
|
|
294
|
+
const reportable = t.runs > 0 && !onlyFreeDryRuns(t);
|
|
295
|
+
if (reportable) {
|
|
296
|
+
lines.push(...totalsLines(t));
|
|
297
|
+
if (result.studies.length > 0)
|
|
298
|
+
lines.push("", "per study:", ...result.studies.map((row) => {
|
|
299
|
+
const rate = row.passRate === undefined ? "no verdicts" : `${row.passed} of ${row.judged} passed`;
|
|
300
|
+
const duration = row.medianDurationMs === undefined
|
|
301
|
+
? "no timed live runs"
|
|
302
|
+
: `median ${minutes(row.medianDurationMs)} over ${row.durationSamples}`;
|
|
303
|
+
const cost = row.medianCostUsd === undefined
|
|
304
|
+
? "no priced participant/desktop runs"
|
|
305
|
+
: `participant/desktop median ${money(row.medianCostUsd)} over ${row.costSamples}`;
|
|
306
|
+
return `- ${row.study}: ${plural(row.runs, "run")}, ${row.live} live; ${rate}; ${duration}; known study spend ${knownMoney(row.costs.estimatedTotalUsd)}; ${cost}${unpricedTail(row.unpricedRuns, row.costs.analysisUnpricedAttempts)}`;
|
|
307
|
+
}));
|
|
308
|
+
if (result.days.length > 0)
|
|
309
|
+
lines.push("", "by day:", ...result.days.map(dayLine));
|
|
253
310
|
}
|
|
254
311
|
if (result.unreadable.length > 0)
|
|
255
312
|
lines.push("", `unreadable run directories: ${result.unreadable.join(", ")}`);
|
|
256
|
-
|
|
313
|
+
if (reportable)
|
|
314
|
+
lines.push("", result.note);
|
|
257
315
|
return `${lines.join("\n")}\n`;
|
|
258
316
|
}
|