@sema-agent/server 1.323.0 → 2.0.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/dist/approval-hmac.d.ts +40 -0
- package/dist/approval-hmac.js +67 -0
- package/dist/approval.d.ts +31 -0
- package/dist/approval.js +72 -4
- package/dist/audit.d.ts +26 -0
- package/dist/audit.js +40 -1
- package/dist/auth-bridge.d.ts +10 -0
- package/dist/auth-bridge.js +47 -4
- package/dist/auth-keys.d.ts +19 -0
- package/dist/auth-keys.js +13 -0
- package/dist/bake-runner/main.d.ts +5 -0
- package/dist/bake-runner/main.js +43 -4
- package/dist/bake-runner/protocol.d.ts +57 -0
- package/dist/bake-runner/protocol.js +58 -3
- package/dist/bake-runner/runner.d.ts +54 -0
- package/dist/bake-runner/runner.js +87 -5
- package/dist/bench/l8/artifact.d.ts +63 -0
- package/dist/bench/l8/artifact.js +61 -2
- package/dist/bench/l8/escape.d.ts +36 -0
- package/dist/bench/l8/escape.js +25 -0
- package/dist/bench/l8/index.d.ts +14 -0
- package/dist/bench/l8/index.js +14 -0
- package/dist/bench/l8/probes.d.ts +74 -0
- package/dist/bench/l8/probes.js +60 -0
- package/dist/bench/l8/run-probes.d.ts +43 -0
- package/dist/bench/l8/run-probes.js +45 -2
- package/dist/bench/s1/arms.d.ts +126 -0
- package/dist/bench/s1/arms.js +188 -13
- package/dist/bench/s1/live-deps.d.ts +66 -0
- package/dist/bench/s1/live-deps.js +249 -11
- package/dist/bench/s1/oracle.d.ts +49 -0
- package/dist/bench/s1/oracle.js +36 -1
- package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
- package/dist/bench/s1/repair-oracle-adapter.js +30 -0
- package/dist/bench/s1/reviewer.d.ts +38 -0
- package/dist/bench/s1/reviewer.js +34 -0
- package/dist/bench/s1/row.d.ts +77 -0
- package/dist/bench/s1/row.js +62 -0
- package/dist/bench/s1/run-firm.d.ts +47 -0
- package/dist/bench/s1/run-firm.js +70 -4
- package/dist/bench/s1/runner-ctx.d.ts +71 -0
- package/dist/bench/s1/runner-ctx.js +36 -0
- package/dist/bench/s1/tasks.d.ts +108 -0
- package/dist/bench/s1/tasks.js +115 -0
- package/dist/boot-reclaim.d.ts +19 -0
- package/dist/boot-reclaim.js +20 -0
- package/dist/brain.d.ts +25 -0
- package/dist/brain.js +61 -1
- package/dist/budget.d.ts +66 -0
- package/dist/budget.js +128 -4
- package/dist/capabilities/builtin-tools.d.ts +3 -0
- package/dist/capabilities/builtin-tools.js +3 -0
- package/dist/capabilities/center-plugins.d.ts +17 -1
- package/dist/capabilities/center-plugins.js +45 -4
- package/dist/capabilities/center-prompts.d.ts +46 -0
- package/dist/capabilities/center-prompts.js +57 -3
- package/dist/capabilities/code-review-council.d.ts +28 -0
- package/dist/capabilities/code-review-council.js +40 -7
- package/dist/capabilities/collab-wire.d.ts +2 -0
- package/dist/capabilities/collab-workflows.d.ts +7 -0
- package/dist/capabilities/collab-workflows.js +44 -1
- package/dist/capabilities/oa-tools.d.ts +6 -0
- package/dist/capabilities/oa-tools.js +10 -0
- package/dist/capabilities/prompt.d.ts +14 -0
- package/dist/capabilities/prompt.js +14 -0
- package/dist/capabilities/prompts/code-review.d.ts +14 -0
- package/dist/capabilities/prompts/code-review.js +14 -0
- package/dist/capabilities/prompts/identity.d.ts +6 -0
- package/dist/capabilities/prompts/identity.js +6 -0
- package/dist/capabilities/prompts/team.d.ts +4 -0
- package/dist/capabilities/prompts/team.js +4 -0
- package/dist/capabilities/repo-tools.d.ts +11 -0
- package/dist/capabilities/repo-tools.js +8 -0
- package/dist/capabilities/sandbox-file-send.d.ts +95 -0
- package/dist/capabilities/sandbox-file-send.js +91 -3
- package/dist/capabilities/scenarios.d.ts +130 -0
- package/dist/capabilities/scenarios.js +180 -7
- package/dist/capabilities/select-environment-tool.d.ts +7 -0
- package/dist/capabilities/select-environment-tool.js +30 -0
- package/dist/capabilities/send-user-file-tool.d.ts +33 -0
- package/dist/capabilities/send-user-file-tool.js +65 -1
- package/dist/capabilities/skills.d.ts +29 -0
- package/dist/capabilities/skills.js +13 -2
- package/dist/capabilities/team.d.ts +22 -0
- package/dist/capabilities/team.js +22 -2
- package/dist/capabilities/tool-defer.d.ts +26 -0
- package/dist/capabilities/tool-defer.js +3 -0
- package/dist/config-center/apply-effective.d.ts +65 -0
- package/dist/config-center/apply-effective.js +204 -12
- package/dist/config-center/http-client.d.ts +34 -0
- package/dist/config-center/http-client.js +68 -0
- package/dist/config-center/restart-signal.d.ts +22 -0
- package/dist/config-center/restart-signal.js +39 -0
- package/dist/config-center/skills-mcp.d.ts +20 -1
- package/dist/config-center/skills-mcp.js +42 -7
- package/dist/config-center/types.d.ts +92 -1
- package/dist/config-lkg.d.ts +12 -0
- package/dist/config-lkg.js +41 -0
- package/dist/config-provider.d.ts +78 -0
- package/dist/config-provider.js +165 -2
- package/dist/config-types.d.ts +546 -0
- package/dist/config.d.ts +64 -0
- package/dist/config.js +455 -60
- package/dist/degenerate-instrument.d.ts +38 -0
- package/dist/degenerate-instrument.js +55 -3
- package/dist/elicitation.d.ts +39 -0
- package/dist/elicitation.js +87 -3
- package/dist/env-facts.d.ts +61 -0
- package/dist/env-facts.js +73 -7
- package/dist/fleet/fleet-bus.d.ts +185 -0
- package/dist/fleet/fleet-bus.js +333 -27
- package/dist/fleet/subagent-tail-bus.d.ts +11 -0
- package/dist/fleet/subagent-tail-bus.js +33 -2
- package/dist/fleet-client.d.ts +38 -0
- package/dist/fleet-client.js +44 -9
- package/dist/fleet-lease.d.ts +46 -0
- package/dist/fleet-lease.js +73 -5
- package/dist/hooks/branch-transcript.d.ts +8 -0
- package/dist/hooks/branch-transcript.js +33 -0
- package/dist/hooks/cc-stop-prompt.d.ts +42 -0
- package/dist/hooks/cc-stop-prompt.js +43 -1
- package/dist/hooks/hook-llm.d.ts +15 -0
- package/dist/hooks/hook-llm.js +47 -0
- package/dist/hooks/hook-runner.d.ts +89 -0
- package/dist/hooks/hook-runner.js +327 -18
- package/dist/http/idempotency.d.ts +31 -0
- package/dist/http/idempotency.js +34 -0
- package/dist/http/principal-gate.d.ts +17 -0
- package/dist/http/principal-gate.js +35 -3
- package/dist/http/route-ctx.d.ts +36 -0
- package/dist/http/routes/approvals-assistant.d.ts +25 -0
- package/dist/http/routes/approvals-assistant.js +253 -23
- package/dist/http/routes/attachments.js +22 -4
- package/dist/http/routes/capabilities.d.ts +7 -0
- package/dist/http/routes/capabilities.js +202 -1
- package/dist/http/routes/fleet.d.ts +6 -0
- package/dist/http/routes/fleet.js +94 -5
- package/dist/http/routes/images.d.ts +17 -0
- package/dist/http/routes/images.js +222 -14
- package/dist/http/routes/leader.d.ts +7 -0
- package/dist/http/routes/leader.js +10 -0
- package/dist/http/routes/memory-policy.d.ts +6 -0
- package/dist/http/routes/memory-policy.js +38 -6
- package/dist/http/routes/notify-wake.d.ts +10 -0
- package/dist/http/routes/notify-wake.js +19 -3
- package/dist/http/routes/observability.d.ts +6 -0
- package/dist/http/routes/observability.js +19 -2
- package/dist/http/routes/runs.d.ts +15 -0
- package/dist/http/routes/runs.js +464 -41
- package/dist/http/routes/session-sync.d.ts +15 -0
- package/dist/http/routes/session-sync.js +229 -19
- package/dist/http/routes/sessions-list.d.ts +6 -0
- package/dist/http/routes/sessions-list.js +35 -4
- package/dist/http/routes/sessions.d.ts +14 -0
- package/dist/http/routes/sessions.js +176 -31
- package/dist/http/routes/side-query.d.ts +8 -0
- package/dist/http/routes/side-query.js +26 -1
- package/dist/http/routes/tasks.d.ts +18 -0
- package/dist/http/routes/tasks.js +501 -38
- package/dist/http/routes/trace-usage.d.ts +10 -0
- package/dist/http/routes/trace-usage.js +66 -14
- package/dist/http/routes/workflows.d.ts +12 -0
- package/dist/http/routes/workflows.js +180 -19
- package/dist/http/run-meta.d.ts +11 -0
- package/dist/http/run-meta.js +6 -0
- package/dist/http/send.d.ts +19 -0
- package/dist/http/send.js +11 -0
- package/dist/http/server.d.ts +255 -0
- package/dist/http/server.js +921 -75
- package/dist/http/sse-log.d.ts +15 -0
- package/dist/http/sse-log.js +16 -0
- package/dist/http/tar.d.ts +9 -0
- package/dist/http/tar.js +21 -5
- package/dist/http/wire-gate.d.ts +9 -0
- package/dist/http/wire-gate.js +9 -0
- package/dist/http/wire-types.d.ts +187 -0
- package/dist/http/workspace-content.d.ts +8 -0
- package/dist/http/workspace-content.js +10 -0
- package/dist/images/bake-validate.d.ts +63 -0
- package/dist/images/bake-validate.js +71 -1
- package/dist/images/manifest.d.ts +19 -0
- package/dist/images/manifest.js +6 -1
- package/dist/index.d.ts +1 -5
- package/dist/index.js +10 -5
- package/dist/key-resolver.d.ts +23 -0
- package/dist/key-resolver.js +27 -2
- package/dist/leader/diffout.d.ts +23 -0
- package/dist/leader/diffout.js +8 -1
- package/dist/leader/diffup.d.ts +32 -0
- package/dist/leader/diffup.js +43 -0
- package/dist/leader/endpoint.d.ts +20 -0
- package/dist/leader/endpoint.js +25 -2
- package/dist/leader/fanout.d.ts +60 -0
- package/dist/leader/fanout.js +29 -3
- package/dist/leader/grader-env-factory.d.ts +74 -0
- package/dist/leader/grader-env-factory.js +62 -3
- package/dist/leader/leader.d.ts +97 -0
- package/dist/leader/leader.js +151 -4
- package/dist/leader/merge.d.ts +94 -0
- package/dist/leader/merge.js +112 -9
- package/dist/leader/planner.d.ts +52 -0
- package/dist/leader/planner.js +47 -3
- package/dist/leader/repair-oracle.d.ts +61 -0
- package/dist/leader/repair-oracle.js +59 -1
- package/dist/leader/repair-wire.d.ts +78 -0
- package/dist/leader/repair-wire.js +79 -2
- package/dist/leader/wire.d.ts +79 -0
- package/dist/leader/wire.js +255 -8
- package/dist/lsp/e2b-bridge.d.ts +16 -0
- package/dist/lsp/e2b-bridge.js +32 -4
- package/dist/lsp/e2b-manager.d.ts +10 -0
- package/dist/lsp/e2b-manager.js +18 -2
- package/dist/lsp/lsp-frames.d.ts +12 -0
- package/dist/lsp/lsp-frames.js +12 -0
- package/dist/lsp/manager.d.ts +12 -0
- package/dist/lsp/manager.js +35 -2
- package/dist/lsp/types.d.ts +10 -0
- package/dist/lsp/ws-transport.d.ts +12 -0
- package/dist/lsp/ws-transport.js +53 -5
- package/dist/lsp-evict.d.ts +14 -0
- package/dist/lsp-evict.js +15 -1
- package/dist/main.js +2132 -96
- package/dist/memory-export.d.ts +1 -0
- package/dist/memory-export.js +4 -0
- package/dist/memory-scope.d.ts +49 -0
- package/dist/memory-scope.js +87 -4
- package/dist/memory-sync-client.d.ts +24 -0
- package/dist/memory-sync-client.js +41 -2
- package/dist/memory-sync.d.ts +23 -0
- package/dist/memory-sync.js +70 -1
- package/dist/model-select.d.ts +39 -0
- package/dist/model-select.js +42 -1
- package/dist/observability/cost-quota.d.ts +20 -0
- package/dist/observability/cost-quota.js +4 -0
- package/dist/observability/cost-taxonomy.d.ts +45 -0
- package/dist/observability/cost-taxonomy.js +34 -0
- package/dist/observability/logger.d.ts +1 -0
- package/dist/observability/logger.js +6 -0
- package/dist/observability/metrics.d.ts +13 -0
- package/dist/observability/metrics.js +63 -0
- package/dist/observability/otel-exporter.d.ts +9 -0
- package/dist/observability/otel-exporter.js +11 -3
- package/dist/observability/principal-context.d.ts +9 -0
- package/dist/observability/principal-context.js +9 -0
- package/dist/observability/prompt-manifest.d.ts +37 -0
- package/dist/observability/prompt-manifest.js +35 -1
- package/dist/observability/rate-limit.d.ts +10 -0
- package/dist/observability/rate-limit.js +1 -0
- package/dist/observability/tool-trace.d.ts +24 -0
- package/dist/observability/tool-trace.js +41 -1
- package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
- package/dist/orchestration/hardened-vm-runner.js +119 -4
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
- package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
- package/dist/orchestration/hardened-vm-worker.js +27 -0
- package/dist/orchestration/subagent-steer.d.ts +44 -0
- package/dist/orchestration/subagent-steer.js +45 -1
- package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
- package/dist/orchestration/workflow-agent-steer.js +80 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
- package/dist/orchestration/workflow-completion-inbox.js +283 -32
- package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
- package/dist/orchestration/workflow-notify-journal.js +187 -13
- package/dist/parked-decide.d.ts +61 -0
- package/dist/parked-decide.js +58 -1
- package/dist/per-task-image.d.ts +54 -0
- package/dist/per-task-image.js +41 -0
- package/dist/plan-cache-probe.d.ts +35 -0
- package/dist/plan-cache-probe.js +18 -3
- package/dist/plugins/approval-exemption-store.d.ts +7 -0
- package/dist/plugins/approval-exemption-store.js +28 -2
- package/dist/plugins/approval-store-sql.d.ts +64 -0
- package/dist/plugins/approval-store-sql.js +32 -0
- package/dist/plugins/background-agent-store-sql.d.ts +55 -0
- package/dist/plugins/background-agent-store-sql.js +91 -4
- package/dist/plugins/background-shell-support.d.ts +98 -0
- package/dist/plugins/background-shell-support.js +117 -13
- package/dist/plugins/blob-backend.d.ts +104 -0
- package/dist/plugins/blob-backend.js +163 -6
- package/dist/plugins/breaker-state-sql.d.ts +65 -1
- package/dist/plugins/breaker-state-sql.js +46 -8
- package/dist/plugins/caching-session-store.d.ts +42 -0
- package/dist/plugins/caching-session-store.js +63 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
- package/dist/plugins/checkpoint-store-sql.js +239 -11
- package/dist/plugins/file-outcome-sink.d.ts +4 -0
- package/dist/plugins/file-outcome-sink.js +9 -0
- package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
- package/dist/plugins/file-resume-anchor-store.js +43 -4
- package/dist/plugins/file-run-store.d.ts +90 -0
- package/dist/plugins/file-run-store.js +145 -13
- package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
- package/dist/plugins/file-snapshot-store-sql.js +178 -10
- package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
- package/dist/plugins/file-workflow-journal-store.js +10 -0
- package/dist/plugins/fork-routing-session-store.d.ts +47 -0
- package/dist/plugins/fork-routing-session-store.js +51 -3
- package/dist/plugins/host-platform.d.ts +69 -0
- package/dist/plugins/host-platform.js +81 -2
- package/dist/plugins/image-bake-store-sql.d.ts +136 -1
- package/dist/plugins/image-bake-store-sql.js +241 -7
- package/dist/plugins/image-index-sql.d.ts +46 -0
- package/dist/plugins/image-index-sql.js +113 -4
- package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
- package/dist/plugins/k8s-bg-scripts.js +88 -4
- package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
- package/dist/plugins/k8s-exec-protocol.js +41 -0
- package/dist/plugins/local-checkpoint-store.d.ts +40 -0
- package/dist/plugins/local-checkpoint-store.js +86 -7
- package/dist/plugins/local-session-store.d.ts +157 -0
- package/dist/plugins/local-session-store.js +289 -34
- package/dist/plugins/local-task-attachment-store.js +14 -2
- package/dist/plugins/mailbox-store-sql.d.ts +38 -0
- package/dist/plugins/mailbox-store-sql.js +39 -6
- package/dist/plugins/memory-engine-pg.d.ts +30 -0
- package/dist/plugins/memory-engine-pg.js +122 -4
- package/dist/plugins/memory-engine-tidb.d.ts +26 -0
- package/dist/plugins/memory-engine-tidb.js +115 -5
- package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
- package/dist/plugins/memory-engine-vector-util.js +5 -0
- package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
- package/dist/plugins/memory-resume-anchor-store.js +17 -0
- package/dist/plugins/memory-run-store.d.ts +63 -0
- package/dist/plugins/memory-run-store.js +73 -8
- package/dist/plugins/memory-session-policy-store.d.ts +17 -0
- package/dist/plugins/memory-session-policy-store.js +17 -0
- package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
- package/dist/plugins/memory-sync-store-pg.js +45 -2
- package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
- package/dist/plugins/memory-sync-store-tidb.js +31 -1
- package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
- package/dist/plugins/outcome-ledger-sql.js +97 -3
- package/dist/plugins/pg-approval-store.d.ts +7 -0
- package/dist/plugins/pg-approval-store.js +7 -0
- package/dist/plugins/pg-breaker-state.d.ts +6 -0
- package/dist/plugins/pg-breaker-state.js +6 -0
- package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
- package/dist/plugins/pg-checkpoint-store.js +8 -0
- package/dist/plugins/pg-cost-quota.d.ts +17 -0
- package/dist/plugins/pg-cost-quota.js +6 -0
- package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/pg-file-snapshot-store.js +6 -0
- package/dist/plugins/pg-image-bake.d.ts +9 -0
- package/dist/plugins/pg-image-bake.js +9 -0
- package/dist/plugins/pg-image-index.d.ts +9 -0
- package/dist/plugins/pg-image-index.js +9 -0
- package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
- package/dist/plugins/pg-outcome-ledger.js +9 -0
- package/dist/plugins/pg-pool.d.ts +50 -0
- package/dist/plugins/pg-pool.js +78 -0
- package/dist/plugins/pg-query.d.ts +11 -0
- package/dist/plugins/pg-rate-limiter.d.ts +23 -0
- package/dist/plugins/pg-rate-limiter.js +12 -2
- package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/pg-resume-anchor-store.js +5 -0
- package/dist/plugins/pg-run-store.d.ts +7 -0
- package/dist/plugins/pg-run-store.js +7 -0
- package/dist/plugins/pg-safe-json.d.ts +13 -0
- package/dist/plugins/pg-safe-json.js +40 -4
- package/dist/plugins/pg-session-policy-store.d.ts +5 -0
- package/dist/plugins/pg-session-policy-store.js +5 -0
- package/dist/plugins/pg-session-storage.d.ts +72 -0
- package/dist/plugins/pg-session-storage.js +152 -20
- package/dist/plugins/pg-session-store.d.ts +10 -0
- package/dist/plugins/pg-session-store.js +10 -0
- package/dist/plugins/pg-tool-result-store.d.ts +7 -0
- package/dist/plugins/pg-tool-result-store.js +7 -0
- package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-journal-store.js +7 -0
- package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
- package/dist/plugins/pg-workflow-run-store.js +7 -0
- package/dist/plugins/posix-shell-fs.d.ts +3 -0
- package/dist/plugins/posix-shell-fs.js +31 -1
- package/dist/plugins/remote-env-adb.d.ts +25 -0
- package/dist/plugins/remote-env-adb.js +95 -12
- package/dist/plugins/remote-env-e2b.d.ts +146 -0
- package/dist/plugins/remote-env-e2b.js +371 -40
- package/dist/plugins/remote-env-file-error.d.ts +34 -0
- package/dist/plugins/remote-env-file-error.js +37 -0
- package/dist/plugins/remote-env-host.d.ts +151 -0
- package/dist/plugins/remote-env-host.js +468 -70
- package/dist/plugins/remote-env-k8s.d.ts +135 -0
- package/dist/plugins/remote-env-k8s.js +318 -32
- package/dist/plugins/remote-env-local-docker.d.ts +65 -0
- package/dist/plugins/remote-env-local-docker.js +149 -24
- package/dist/plugins/remote-env-ssh.d.ts +35 -0
- package/dist/plugins/remote-env-ssh.js +117 -20
- package/dist/plugins/remote-scratchpad.d.ts +38 -0
- package/dist/plugins/remote-scratchpad.js +32 -2
- package/dist/plugins/remote-shell.d.ts +22 -0
- package/dist/plugins/remote-shell.js +27 -1
- package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
- package/dist/plugins/resume-anchor-store-sql.js +11 -0
- package/dist/plugins/roster-store-sql.d.ts +27 -0
- package/dist/plugins/roster-store-sql.js +54 -0
- package/dist/plugins/run-store-sql.d.ts +194 -0
- package/dist/plugins/run-store-sql.js +210 -9
- package/dist/plugins/s3-presign.d.ts +20 -0
- package/dist/plugins/s3-presign.js +49 -2
- package/dist/plugins/scheduler-support.d.ts +12 -0
- package/dist/plugins/scheduler-support.js +75 -3
- package/dist/plugins/send-file-ledger.d.ts +15 -0
- package/dist/plugins/send-file-ledger.js +53 -4
- package/dist/plugins/send-user-file.d.ts +77 -0
- package/dist/plugins/send-user-file.js +92 -4
- package/dist/plugins/session-policy-store-sql.d.ts +15 -0
- package/dist/plugins/session-policy-store-sql.js +75 -3
- package/dist/plugins/session-store.d.ts +45 -0
- package/dist/plugins/session-store.js +51 -0
- package/dist/plugins/sql-driver.d.ts +77 -0
- package/dist/plugins/sql-driver.js +4 -0
- package/dist/plugins/sql-escape.d.ts +8 -0
- package/dist/plugins/sql-escape.js +8 -0
- package/dist/plugins/sql-row-helpers.d.ts +25 -0
- package/dist/plugins/sql-row-helpers.js +25 -0
- package/dist/plugins/store-backend.d.ts +103 -0
- package/dist/plugins/store-backend.js +120 -27
- package/dist/plugins/store-contracts.d.ts +62 -0
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +60 -0
- package/dist/plugins/task-attachment-store.js +49 -3
- package/dist/plugins/task-list-store-sql.d.ts +25 -0
- package/dist/plugins/task-list-store-sql.js +21 -0
- package/dist/plugins/tidb-approval-store.d.ts +6 -0
- package/dist/plugins/tidb-approval-store.js +6 -0
- package/dist/plugins/tidb-breaker-state.d.ts +5 -0
- package/dist/plugins/tidb-breaker-state.js +5 -0
- package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
- package/dist/plugins/tidb-checkpoint-store.js +7 -0
- package/dist/plugins/tidb-cost-quota.d.ts +6 -0
- package/dist/plugins/tidb-cost-quota.js +1 -0
- package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
- package/dist/plugins/tidb-file-snapshot-store.js +6 -0
- package/dist/plugins/tidb-image-bake.d.ts +8 -0
- package/dist/plugins/tidb-image-bake.js +8 -0
- package/dist/plugins/tidb-image-index.d.ts +8 -0
- package/dist/plugins/tidb-image-index.js +8 -0
- package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
- package/dist/plugins/tidb-outcome-ledger.js +10 -0
- package/dist/plugins/tidb-pool.d.ts +56 -0
- package/dist/plugins/tidb-pool.js +181 -1
- package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
- package/dist/plugins/tidb-rate-limiter.js +5 -2
- package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
- package/dist/plugins/tidb-resume-anchor-store.js +5 -0
- package/dist/plugins/tidb-run-store.d.ts +7 -0
- package/dist/plugins/tidb-run-store.js +7 -0
- package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
- package/dist/plugins/tidb-session-policy-store.js +5 -0
- package/dist/plugins/tidb-session-storage.d.ts +43 -0
- package/dist/plugins/tidb-session-storage.js +62 -3
- package/dist/plugins/tidb-session-store.d.ts +142 -0
- package/dist/plugins/tidb-session-store.js +264 -16
- package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
- package/dist/plugins/tidb-tool-result-store.js +7 -0
- package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
- package/dist/plugins/tidb-workflow-journal-store.js +7 -0
- package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
- package/dist/plugins/tidb-workflow-run-store.js +8 -0
- package/dist/plugins/tool-result-store-sql.d.ts +58 -0
- package/dist/plugins/tool-result-store-sql.js +38 -2
- package/dist/plugins/web-search.d.ts +35 -0
- package/dist/plugins/web-search.js +45 -9
- package/dist/plugins/workflow-journal-limits.d.ts +10 -0
- package/dist/plugins/workflow-journal-limits.js +10 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
- package/dist/plugins/workflow-journal-store-sql.js +58 -2
- package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
- package/dist/plugins/workflow-run-store-sql.js +84 -6
- package/dist/plugins/worktree-isolation.d.ts +45 -0
- package/dist/plugins/worktree-isolation.js +105 -6
- package/dist/plugins/write-behind-counter.d.ts +56 -1
- package/dist/plugins/write-behind-counter.js +53 -14
- package/dist/principal-jwt.d.ts +24 -0
- package/dist/principal-jwt.js +60 -5
- package/dist/project-memory.d.ts +22 -0
- package/dist/project-memory.js +144 -15
- package/dist/prompts-domain-validate.d.ts +28 -0
- package/dist/prompts-domain-validate.js +42 -1
- package/dist/question.d.ts +33 -0
- package/dist/question.js +69 -2
- package/dist/resource-suspend.d.ts +21 -0
- package/dist/resource-suspend.js +16 -0
- package/dist/router/route-orchestration.d.ts +78 -0
- package/dist/router/route-orchestration.js +77 -0
- package/dist/run-local.d.ts +32 -0
- package/dist/run-local.js +172 -8
- package/dist/runs.d.ts +189 -4
- package/dist/runs.js +465 -24
- package/dist/runtime-caps-resolver.d.ts +106 -0
- package/dist/runtime-caps-resolver.js +89 -4
- package/dist/runtime-governance.d.ts +84 -0
- package/dist/runtime-governance.js +127 -1
- package/dist/sandbox-pkg-source.d.ts +23 -0
- package/dist/sandbox-pkg-source.js +37 -0
- package/dist/sealed-key.d.ts +54 -0
- package/dist/sealed-key.js +68 -3
- package/dist/security.d.ts +108 -0
- package/dist/security.js +145 -6
- package/dist/sema-registry.d.ts +21 -0
- package/dist/sema-registry.js +21 -0
- package/dist/session-leaf-bus.d.ts +31 -0
- package/dist/session-leaf-bus.js +32 -0
- package/dist/session-sync-content.d.ts +46 -0
- package/dist/session-sync-content.js +47 -1
- package/dist/session-sync-kernel.d.ts +89 -0
- package/dist/session-sync-kernel.js +48 -3
- package/dist/session-sync.d.ts +125 -0
- package/dist/session-sync.js +181 -8
- package/dist/session-titler.d.ts +26 -0
- package/dist/session-titler.js +41 -7
- package/dist/session-watch.d.ts +53 -1
- package/dist/session-watch.js +73 -9
- package/dist/sighup-idle.d.ts +30 -0
- package/dist/sighup-idle.js +12 -1
- package/dist/spec-fields.d.ts +91 -3
- package/dist/spec-fields.js +116 -4
- package/dist/task-cwd.d.ts +50 -0
- package/dist/task-cwd.js +68 -1
- package/dist/task-mcp.d.ts +47 -0
- package/dist/task-mcp.js +29 -0
- package/dist/task-settings.d.ts +175 -0
- package/dist/task-settings.js +226 -11
- package/dist/task-workflow.d.ts +67 -0
- package/dist/task-workflow.js +75 -8
- package/dist/tool-approval.d.ts +91 -0
- package/dist/tool-approval.js +215 -0
- package/dist/trace/artifacts.d.ts +9 -0
- package/dist/trace/artifacts.js +30 -5
- package/dist/trace/core-keyset-guard.d.ts +18 -0
- package/dist/trace/ledger-sink.d.ts +43 -0
- package/dist/trace/ledger-sink.js +64 -5
- package/dist/trace/project.d.ts +133 -0
- package/dist/trace/project.js +189 -2
- package/dist/trace/redact.d.ts +19 -0
- package/dist/trace/redact.js +66 -9
- package/dist/usage-analytics.d.ts +26 -0
- package/dist/usage-analytics.js +26 -3
- package/package.json +1 -1
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S1 value-verdict harness — the REAL `ProfileDeps` factory (the LIVE make-real wiring). SPEC-S1-value-harness.md
|
|
3
|
+
* §11 "the wiring of ProfileDeps to the REAL core entrypoints + REAL E2B worker/grader envs". This module
|
|
4
|
+
* ASSEMBLES a bench runtime — createBrain(DeepSeek) + a real `Runner` + a real E2B WORKER env + a DISTINCT E2B
|
|
5
|
+
* GRADER env + createLeaderRunner for TEAM — and returns a `ProfileDeps` whose EVERY seam runs the REAL engine/
|
|
6
|
+
* oracle. The deterministic driver (`run-firm.ts --dry-run`) injects a MOCK; this is the clay-gated live path.
|
|
7
|
+
*
|
|
8
|
+
* 🔴 ANTI-REWARD-HACK (oracle.ts §, runner-ctx.ts §5.1): the oracle ALWAYS grades in a env that is a DISTINCT
|
|
9
|
+
* object from the worker env. We provision a SEPARATE E2B sandbox for the grader and transfer the worker's
|
|
10
|
+
* COMMITTED tree into it via `git bundle` (export from the worker sandbox → import into the grader sandbox) —
|
|
11
|
+
* so the grader's checkout is the worker's HEAD, but the grader sandbox can never be tampered by the worker
|
|
12
|
+
* (its hidden tests + its exec all run in a sandbox the worker never touched). `assertDistinctEnvs` is the
|
|
13
|
+
* build-time guard; the structural separation is the real boundary.
|
|
14
|
+
*
|
|
15
|
+
* 🔴 TRAP TASKS RUN ISOLATED (the task prompt): every worker leg runs inside an E2B Firecracker VM
|
|
16
|
+
* (`RemoteContainerExecutionEnv`), NEVER the bare host — a C4/trap that reaches for a dangerous action is
|
|
17
|
+
* contained by the VM boundary (`capabilities.isolation === true`).
|
|
18
|
+
*
|
|
19
|
+
* 🔴 OBJECTIVE ORACLE ONLY (row.ts §): `runOracle` runs `runExecGate` over real exit codes in the grader env;
|
|
20
|
+
* there is NO LLM-judge in the numerator. The LLM is only a GATE inside an arm (the verify/repair/reviewer).
|
|
21
|
+
*
|
|
22
|
+
* 🔴 HONEST GAPS (flagged, NOT stubbed): the per-cell worker/grader env LIFECYCLE (provision → run → grade →
|
|
23
|
+
* destroy) is owned by `buildLiveDeps`, which returns a `ProfileDeps` bound to ONE (trap, seed) cell — the
|
|
24
|
+
* driver constructs a fresh `buildLiveDeps` per cell and disposes it after the row is emitted (so a hung cell's
|
|
25
|
+
* sandboxes are reaped). `runCounterfactualOracle` is DELIBERATELY OMITTED (a real ablation — re-running the
|
|
26
|
+
* SAME (trap,seed) with the gate DISABLED into a FRESH worker — is TODO); absent ⇒ buildCounterfactual returns
|
|
27
|
+
* undefined ⇒ the metric tool records UNVERIFIED-WITHHELD (NO avoided-loss credit), the honest "not measured"
|
|
28
|
+
* choice. The previous `runCounterfactualOracle: runOracle` self-alias re-graded the IDENTICAL post-gate tree and
|
|
29
|
+
* auto-credited EVERY withhold as CORRECTLY-WITHHELD (a tautology) — removed.
|
|
30
|
+
*
|
|
31
|
+
* 🔴 TEAM (the leader arm): the leader INTEGRATES + PUSHES to a per-cell `git://127.0.0.1` durable remote (served by
|
|
32
|
+
* a local `git daemon` — the wire validator forbids file://). On a delivered run the harness clones that
|
|
33
|
+
* integrated tree INTO state.worker, so `runOracle` grades the REAL integrated output in the DISTINCT grader (the
|
|
34
|
+
* same anti-reward-hack transfer path SOLO/SUP use). If the integrated tree can't be imported, the cell is
|
|
35
|
+
* `infraFailed` (EXCLUDED) — NEVER a fabricated uniform delivered=false loss for the whole TEAM column.
|
|
36
|
+
*/
|
|
1
37
|
import { Runner, runWithVerification, resumeWithVerification, runRepairLoop, combinePolicies, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, } from "@sema-agent/core";
|
|
2
38
|
import { loadConfig } from "../../config.js";
|
|
3
39
|
import { createBrain } from "../../brain.js";
|
|
@@ -8,14 +44,23 @@ import { createLeaderRunner } from "../../leader/wire.js";
|
|
|
8
44
|
import { runOracle as runStandaloneOracle } from "./oracle.js";
|
|
9
45
|
import { makeRepairOracle } from "./repair-oracle-adapter.js";
|
|
10
46
|
import { assertDistinctEnvs } from "./runner-ctx.js";
|
|
47
|
+
/** The worker/grader workspace root inside each E2B VM. */
|
|
11
48
|
const W = "/home/user";
|
|
49
|
+
/** The repo dir inside each VM where the worker's tree lives + the grader checks out. */
|
|
12
50
|
const REPO = `${W}/repo`;
|
|
51
|
+
/** The grader's base ref for the `delivered` (HEAD advanced past base) signal. The seed commits an empty base. */
|
|
13
52
|
const BASE_REF = "s1-base";
|
|
53
|
+
/** Build the live runtime config from env. GATED on E2B_API_KEY + DEEPSEEK_API_KEY + non-zero MODEL_COST_INPUT/OUTPUT
|
|
54
|
+
* (so C1 is real and maxCostUsd binds). Returns undefined when a required key/price is absent — the driver then
|
|
55
|
+
* refuses the live path with a clear message (never a silent fake run, never a fabricated $0 cost axis). */
|
|
14
56
|
export function liveRuntimeConfigFromEnv(env = process.env) {
|
|
15
57
|
const e2bApiKey = env.E2B_API_KEY;
|
|
16
58
|
const deepseekApiKey = env.DEEPSEEK_API_KEY;
|
|
17
59
|
if (!e2bApiKey || !deepseekApiKey)
|
|
18
60
|
return undefined;
|
|
61
|
+
// 🔴 Cost rates are LOAD-BEARING for the value verdict (C1 + the maxCostUsd safety net). A live run with $0 pricing
|
|
62
|
+
// would produce a fully-green report whose entire cost dimension is fake — the SAME defect class as the fixed
|
|
63
|
+
// delivered-always-false / maxTokens bugs. Fail LOUD (return undefined → driver refuses) when they're missing.
|
|
19
64
|
const costInput = Number(env.MODEL_COST_INPUT ?? "");
|
|
20
65
|
const costOutput = Number(env.MODEL_COST_OUTPUT ?? "");
|
|
21
66
|
if (!(costInput > 0) || !(costOutput > 0))
|
|
@@ -37,20 +82,28 @@ export function liveRuntimeConfigFromEnv(env = process.env) {
|
|
|
37
82
|
...(Number(env.MODEL_COST_CACHE_WRITE ?? "") > 0 ? { costCacheWrite: Number(env.MODEL_COST_CACHE_WRITE) } : {}),
|
|
38
83
|
};
|
|
39
84
|
}
|
|
85
|
+
/** Build the service `ServiceConfig`-shaped brain/pricing ingredients from the live runtime config. We construct a
|
|
86
|
+
* MINIMAL ServiceConfig (only the fields createBrain + buildPricing read) pointed at the DeepSeek gateway. */
|
|
40
87
|
function buildBrainIngredients(rt) {
|
|
88
|
+
// Point the loader at DeepSeek (mirrors the live tests' env stamping) then build the brain/pricing.
|
|
41
89
|
process.env.MODEL_GATEWAY_BASEURL = rt.gatewayBaseUrl;
|
|
42
90
|
process.env.MODEL_ID = rt.modelId;
|
|
43
91
|
process.env.MODEL_API_KEY = rt.deepseekApiKey;
|
|
44
92
|
process.env.MODEL_MAX_TOKENS = String(rt.maxTokens ?? 8000);
|
|
93
|
+
// 🔴 Stamp the cost rates so config.ts builds a NON-ZERO Model.cost → core computes real C1 µUSD + the maxCostUsd
|
|
94
|
+
// gate binds (review fix). Without this the cost half of the value Pareto is a fabricated $0 across all arms.
|
|
45
95
|
process.env.MODEL_COST_INPUT = String(rt.costInput);
|
|
46
96
|
process.env.MODEL_COST_OUTPUT = String(rt.costOutput);
|
|
47
97
|
if (rt.costCacheRead != null)
|
|
48
98
|
process.env.MODEL_COST_CACHE_READ = String(rt.costCacheRead);
|
|
49
99
|
if (rt.costCacheWrite != null)
|
|
50
100
|
process.env.MODEL_COST_CACHE_WRITE = String(rt.costCacheWrite);
|
|
101
|
+
// loadConfig is the authoritative builder of the models/roles/pricing-key catalog (config.ts has no import of
|
|
102
|
+
// this module → no cycle). It reads the DeepSeek env we just stamped above.
|
|
51
103
|
const config = loadConfig();
|
|
52
104
|
const brain = createBrain(config, {});
|
|
53
105
|
const pricing = buildPricing(config.models);
|
|
106
|
+
// 🔴 Defensive assert: if pricing regresses to zero the C1 axis is fake. Catch drift at build, not in a report.
|
|
54
107
|
const p = pricing[rt.modelId];
|
|
55
108
|
if (!p || ((p.inputPer1M ?? 0) === 0 && (p.outputPer1M ?? 0) === 0)) {
|
|
56
109
|
throw new Error(`s1 live: zero pricing for ${rt.modelId} — C1 cost axis would be a fabricated $0 (set MODEL_COST_INPUT/OUTPUT)`);
|
|
@@ -63,6 +116,7 @@ const sh = (env) => async (cmd) => {
|
|
|
63
116
|
throw new Error(`s1 transport: ${r.error.message}`);
|
|
64
117
|
return { code: r.value.exitCode, out: (r.value.stdout + r.value.stderr).trim() };
|
|
65
118
|
};
|
|
119
|
+
/** Provision + connect a fresh E2B sandbox with an empty git repo seeded at the `s1-base` ref. */
|
|
66
120
|
async function provisionSandbox(rt, role, cellId) {
|
|
67
121
|
const env = new RemoteContainerExecutionEnv({
|
|
68
122
|
apiKey: rt.e2bApiKey,
|
|
@@ -75,10 +129,14 @@ async function provisionSandbox(rt, role, cellId) {
|
|
|
75
129
|
throw new Error(`s1 ${role} sandbox connect failed (${cellId}): ${c.error.message}`);
|
|
76
130
|
return env;
|
|
77
131
|
}
|
|
132
|
+
/** Seed a base repo at the `s1-base` ref (the worker commits ON TOP; `delivered` = HEAD advanced past it). When
|
|
133
|
+
* `seedFiles` is given (hazard traps, C6) they are written + committed INTO the base — the worker sees them and may
|
|
134
|
+
* delete them (the survival oracle then checks the sentinel still exists in the committed tree). Absent ⇒ empty base. */
|
|
78
135
|
async function seedBaseRepo(env, seedFiles) {
|
|
136
|
+
// Write each seed file via base64 (no shell-escaping hazard with arbitrary content) into REPO before the base commit.
|
|
79
137
|
const writeCmds = (seedFiles ?? [])
|
|
80
138
|
.map((f) => {
|
|
81
|
-
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
139
|
+
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path; // store relative to REPO
|
|
82
140
|
const b64 = Buffer.from(f.content, "utf8").toString("base64");
|
|
83
141
|
return `mkdir -p "$(dirname '${rel}')" 2>/dev/null; printf %s '${b64}' | base64 -d > '${rel}'`;
|
|
84
142
|
})
|
|
@@ -91,7 +149,18 @@ async function seedBaseRepo(env, seedFiles) {
|
|
|
91
149
|
if (r.code !== 0)
|
|
92
150
|
throw new Error(`s1 seed base repo failed: ${r.out.slice(-400)}`);
|
|
93
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Transfer the WORKER's committed tree into the DISTINCT GRADER sandbox (anti-reward-hack). Exports a `git bundle`
|
|
154
|
+
* of the full history from the worker sandbox, base64-pipes it through the control plane (no shared remote needed),
|
|
155
|
+
* imports it into the grader's repo, and checks out the worker HEAD with the `s1-base` ref recreated. The grader is
|
|
156
|
+
* a SEPARATE sandbox the worker never touched, so its hidden-test run cannot be tampered.
|
|
157
|
+
*/
|
|
94
158
|
async function transferWorkerTreeToGrader(worker, grader) {
|
|
159
|
+
// 🔴 tar-worktree, NOT git bundle/clone (firm-v1/C4 root cause): the grader-side `git clone` is unreliable on BOTH
|
|
160
|
+
// backends — E2B is a platform heisenbug (same code firm-v1 ran green now leaves an unusable .git), Kata is a
|
|
161
|
+
// virtiofs st_dev limit. So the grader NEVER runs git: the worker (where git works) computes the HEAD + s1-base
|
|
162
|
+
// shas and emits a `git archive` tar of the committed tree (no .git); the grader just `tar -x`s plain files.
|
|
163
|
+
// `delivered` (head≠base) comes from the shas. anti-reward-hack unchanged (distinct grader env + restore-before-score).
|
|
95
164
|
const headProbe = await sh(worker)(`cd ${REPO} && git rev-parse HEAD`);
|
|
96
165
|
const baseProbe = await sh(worker)(`cd ${REPO} && git rev-parse ${BASE_REF}`);
|
|
97
166
|
const head = headProbe.out.trim();
|
|
@@ -100,12 +169,14 @@ async function transferWorkerTreeToGrader(worker, grader) {
|
|
|
100
169
|
throw new Error(`s1 worker HEAD unresolved: ${headProbe.out.slice(-200)}`);
|
|
101
170
|
if (!/^[0-9a-f]{40}$/.test(base))
|
|
102
171
|
throw new Error(`s1 worker base ref unresolved: ${baseProbe.out.slice(-200)}`);
|
|
172
|
+
// git archive HEAD = the committed worktree as a tar (no .git), on stdout → base64 to ferry over the exec transport.
|
|
103
173
|
const arch = await sh(worker)(`cd ${REPO} && git archive --format=tar HEAD | base64 -w0`);
|
|
104
174
|
if (arch.code !== 0)
|
|
105
175
|
throw new Error(`s1 worker archive failed: ${arch.out.slice(-400)}`);
|
|
106
176
|
const buf = Buffer.from(arch.out.trim(), "base64");
|
|
107
177
|
if (buf.length === 0)
|
|
108
178
|
throw new Error("s1 worker archive decoded empty on the control plane");
|
|
179
|
+
// Grader: BINARY write the tar (base64-string-over-files.write corrupts; binary is gtest4-proven) + tar -x plain files.
|
|
109
180
|
const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(buf));
|
|
110
181
|
if (!wr.ok)
|
|
111
182
|
throw new Error(`s1 grader tar write failed: ${wr.error.message}`);
|
|
@@ -116,23 +187,47 @@ async function transferWorkerTreeToGrader(worker, grader) {
|
|
|
116
187
|
console.error(`[S1_DEBUG_TAR] head=${head.slice(0, 8)} base=${base.slice(0, 8)} tarBytes=${buf.length} ${ext.out.slice(-60)}`);
|
|
117
188
|
return { head, base };
|
|
118
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Import a git-bundle (base64) into the GRADER sandbox and pin `s1-base` to an EXACT base hash. Shared by the SOLO/SUP
|
|
192
|
+
* path (bundle from the worker sandbox) and the TEAM path (bundle from the control-plane integrated repo — the E2B
|
|
193
|
+
* worker is network-isolated from the leader's git daemon, so the integrated tree is bundled on the control plane and
|
|
194
|
+
* shipped here, NOT cloned from inside E2B). The base hash is set explicitly (never re-derived in the grader → can't
|
|
195
|
+
* collapse to HEAD). Fail-closed: the grader's s1-base MUST resolve to the given hash AND differ from HEAD.
|
|
196
|
+
*/
|
|
119
197
|
async function importBundleB64ToGrader(grader, bundleB64, baseHash) {
|
|
120
198
|
if (!/^[0-9a-f]{40}$/.test(baseHash))
|
|
121
199
|
throw new Error(`s1 grader import: invalid base hash ${JSON.stringify(baseHash)}`);
|
|
122
200
|
const wr = await grader.writeFile(`/tmp/s1.bundle.b64`, bundleB64);
|
|
123
201
|
if (!wr.ok)
|
|
124
202
|
throw new Error(`s1 grader bundle write failed: ${wr.error.message}`);
|
|
203
|
+
// SOLO/SUP path: the b64 is WORKER-ORIGIN (generated by `base64 -w0` inside the same E2B image), so `base64 -d`
|
|
204
|
+
// round-trips cleanly (proven by firm-v1 N=10, 40 SOLO/SUP cells delivered=true). The CONTROL-PLANE-origin b64
|
|
205
|
+
// does NOT round-trip through E2B files.write (firm-v1/C4 dig) — that's why the TEAM path uses a BINARY write
|
|
206
|
+
// (importBundleBinaryToGrader) instead. `test -s` guards an empty decode defensively.
|
|
125
207
|
const imp = await sh(grader)(`set -e; base64 -d /tmp/s1.bundle.b64 > /tmp/s1.bundle; test -s /tmp/s1.bundle; rm -rf ${REPO}; ` +
|
|
126
208
|
`git clone -q /tmp/s1.bundle ${REPO}; cd ${REPO}; ` +
|
|
127
209
|
`git config user.email s1@bench.local; git config user.name s1-bench; ` +
|
|
128
210
|
`git tag -f ${BASE_REF} ${baseHash}`);
|
|
129
211
|
if (imp.code !== 0)
|
|
130
212
|
throw new Error(`s1 grader import failed: ${imp.out.slice(-400)}`);
|
|
213
|
+
// Fail-closed verify: the grader's base MUST resolve to the given base hash AND HEAD must have advanced past it
|
|
214
|
+
// (else `delivered` is meaningless).
|
|
131
215
|
const verify = await sh(grader)(`cd ${REPO} && echo "BASE=$(git rev-parse ${BASE_REF}) HEAD=$(git rev-parse HEAD)"`);
|
|
132
216
|
if (!verify.out.includes(`BASE=${baseHash}`))
|
|
133
217
|
throw new Error(`s1 grader base mismatch: ${verify.out.slice(-200)} expected BASE=${baseHash}`);
|
|
134
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Import a git-bundle (RAW BINARY Buffer) into the GRADER and pin `s1-base` to an EXACT base hash. The TEAM path: the
|
|
221
|
+
* leader's integrated tree is bundled on the CONTROL PLANE, so we ship the bundle as BINARY via E2B files.write
|
|
222
|
+
* (Uint8Array) — 🔴 a base64-STRING through files.write decodes to garbage in the sandbox (firm-v1/C4 dig: a
|
|
223
|
+
* Node-Buffer b64 string, byte-identical to a shell `base64 -w0` locally, came back un-decodable inside E2B; a binary
|
|
224
|
+
* write of the same bytes + `git clone` succeeds, EXIT=0). E2B git 2.39 reads the macOS git 2.50 v2 bundle fine.
|
|
225
|
+
*/
|
|
135
226
|
async function importBundleBinaryToGrader(grader, tarBuffer, shas) {
|
|
227
|
+
// 🔴 TEAM tar-worktree (firm-v1/C4): the leader's INTEGRATED worktree is archived as a tar on the CONTROL PLANE
|
|
228
|
+
// (captureIntegratedTreeToBundle uses `git archive`, no .git). The grader BINARY-writes it + `tar -x`s plain files —
|
|
229
|
+
// NEVER `git clone` (E2B grader-clone is a platform heisenbug; Kata is virtiofs-st_dev-blocked). delivered comes
|
|
230
|
+
// from the worker-computed shas (head≠base), not git in the grader.
|
|
136
231
|
if (!/^[0-9a-f]{40}$/.test(shas.head) || !/^[0-9a-f]{40}$/.test(shas.base))
|
|
137
232
|
throw new Error(`s1 grader import: invalid shas ${JSON.stringify(shas)}`);
|
|
138
233
|
const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(tarBuffer));
|
|
@@ -145,9 +240,11 @@ async function importBundleBinaryToGrader(grader, tarBuffer, shas) {
|
|
|
145
240
|
console.error(`[S1_DEBUG_TAR team] head=${shas.head.slice(0, 8)} base=${shas.base.slice(0, 8)} ${ext.out.slice(-60)}`);
|
|
146
241
|
return shas;
|
|
147
242
|
}
|
|
243
|
+
/** Build the OracleTask the standalone oracle consumes from a trap (stamps graderRepoDir + baseRef). */
|
|
148
244
|
function oracleTaskFromTrap(trap) {
|
|
149
245
|
return { ...trap.oracle, graderRepoDir: REPO, baseRef: BASE_REF };
|
|
150
246
|
}
|
|
247
|
+
/** A GraderTransport bound to a grader sandbox (clone/checkout via exec; hidden-test writes via writeFile). */
|
|
151
248
|
function graderTransport(grader) {
|
|
152
249
|
return {
|
|
153
250
|
exec: async (command) => {
|
|
@@ -163,6 +260,16 @@ function graderTransport(grader) {
|
|
|
163
260
|
},
|
|
164
261
|
};
|
|
165
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* 🔴 THE FACTORY — build a REAL `ProfileDeps` bound to ONE (trap, seed) cell. Provisions a worker E2B sandbox + a
|
|
265
|
+
* DISTINCT grader E2B sandbox (lazily, on first seam call), wires every seam to the REAL core engine/oracle, and
|
|
266
|
+
* returns `{ deps, dispose }`. The driver calls one `buildLiveDeps` per cell and `dispose()`s it after the row.
|
|
267
|
+
*
|
|
268
|
+
* @param rt the live runtime config (DeepSeek + E2B keys + the shared budget).
|
|
269
|
+
* @param trap the class-C trap this cell runs.
|
|
270
|
+
* @param seed the cell's seed (provenance; the durable-approval scope keys on it via buildSupImplSpec).
|
|
271
|
+
* @param cellId a stable id for the cell (used as sandbox metadata for fleet observability).
|
|
272
|
+
*/
|
|
166
273
|
export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
167
274
|
const { brain, models, roles, pricing } = buildBrainIngredients(rt);
|
|
168
275
|
const baseSpec = (objective) => ({
|
|
@@ -172,6 +279,8 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
172
279
|
maxCostUsd: rt.maxCostUsd ?? 1.0,
|
|
173
280
|
limits: { maxTurns: rt.maxTurns ?? 12 },
|
|
174
281
|
});
|
|
282
|
+
// Lazily-provisioned, memoized per-cell sandboxes (so a cell that never runs a seam pays zero VM cost; a seam
|
|
283
|
+
// that throws still leaves them on `state` so dispose() reaps them).
|
|
175
284
|
const state = {};
|
|
176
285
|
const ensureWorker = async () => {
|
|
177
286
|
if (!state.worker) {
|
|
@@ -181,12 +290,15 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
181
290
|
}
|
|
182
291
|
return { env: state.worker, runner: state.runner };
|
|
183
292
|
};
|
|
293
|
+
/** Provision the DISTINCT grader, transfer the worker's committed tree in. Memoized (graded once per cell). */
|
|
184
294
|
const ensureGraderWithWorkerTree = async () => {
|
|
185
295
|
const { env: worker } = await ensureWorker();
|
|
186
296
|
if (!state.grader) {
|
|
187
297
|
state.grader = await provisionSandbox(rt, "grader", cellId);
|
|
188
|
-
assertDistinctEnvs(worker, state.grader);
|
|
298
|
+
assertDistinctEnvs(worker, state.grader); // build-time guard (the structural separation is the real boundary)
|
|
299
|
+
// No grader seedBaseRepo: the grader holds a tar-extracted worktree (no .git at all), so it needs no git identity.
|
|
189
300
|
if (state.teamBundle) {
|
|
301
|
+
// TEAM: extract the control-plane-archived integrated worktree into the grader (tar, no git — same dodge).
|
|
190
302
|
state.shas = await importBundleBinaryToGrader(state.grader, state.teamBundle.buffer, { head: state.teamBundle.head, base: state.teamBundle.base });
|
|
191
303
|
}
|
|
192
304
|
else {
|
|
@@ -195,54 +307,91 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
195
307
|
}
|
|
196
308
|
return state.grader;
|
|
197
309
|
};
|
|
310
|
+
/** Run the OBJECTIVE oracle in the DISTINCT grader env (the measure — runExecGate over real exit codes).
|
|
311
|
+
* @param reSyncWorkerTree when true, RE-TRANSFER the worker's committed tree into the (already-provisioned)
|
|
312
|
+
* grader before grading. The non-repair path grades a STABLE terminal tree once (memoized transfer is
|
|
313
|
+
* correct); the repair loop calls the oracle ONCE PER ATTEMPT against an EVOLVING worker tree, so it MUST
|
|
314
|
+
* re-sync or it would forever grade the frozen attempt-1 snapshot (the grader would never see a fix land). */
|
|
198
315
|
const runOracle = async (reSyncWorkerTree = false) => {
|
|
199
316
|
const { env: worker } = await ensureWorker();
|
|
200
317
|
const grader = await ensureGraderWithWorkerTree();
|
|
201
318
|
if (reSyncWorkerTree)
|
|
202
|
-
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
319
|
+
state.shas = await transferWorkerTreeToGrader(worker, grader); // re-extract the evolving worktree
|
|
203
320
|
const task = { ...oracleTaskFromTrap(trap), ...(state.shas ? { deliveredShas: state.shas } : {}) };
|
|
204
321
|
const v = await runStandaloneOracle(grader, graderTransport(grader), worker, task);
|
|
205
322
|
if (process.env.S1_DEBUG_GIT)
|
|
206
323
|
console.error(`[S1_DEBUG_ORACLE ${trap.id}] delivered=${v.delivered} tests=${v.hiddenTestsGreen} build=${v.buildPassed} inv=${v.invariantsOk} | raw=`, JSON.stringify(v.raw)?.slice(0, 700));
|
|
207
|
-
return v;
|
|
324
|
+
return v; // OracleVerdict is a superset of OracleVerdicts; pickOracleVerdicts narrows it in arms.ts.
|
|
208
325
|
};
|
|
209
326
|
const deps = {
|
|
327
|
+
// ── SOLO: run the impl behind the verify→fix gate via the REAL core runWithVerification ──
|
|
210
328
|
runWithVerification: async (implSpec) => {
|
|
211
329
|
const { runner } = await ensureWorker();
|
|
212
330
|
return runWithVerification(runner, toTaskSpec(baseSpec, implSpec), { maxRounds: rt.maxRounds ?? 2 });
|
|
213
331
|
},
|
|
332
|
+
// ── SUP verify/durable path ──
|
|
333
|
+
// 🔴 durable suspend/resume is ONLY supported at the TOP-LEVEL runTask (core's mapNestedSuspend HARD boundary,
|
|
334
|
+
// design/45 §11 Q6 / design/80 D-B): the NESTED runWithVerification maps a durable pause to status:"failed"
|
|
335
|
+
// (UNEXPECTED_SUSPENDED), so the SUP HITL gate (gated bash → suspend) was ALWAYS infra-failed (caught by the
|
|
336
|
+
// firm-v1 N=1 all-paths smoke: C1/C2-SUP failed at turn 1, unverifiedReason="suspended", checkpointGate present).
|
|
337
|
+
// FIX: run the durable task at the TOP LEVEL so the suspend propagates as status:"suspended" + checkpointToken;
|
|
338
|
+
// driveSupSuspendResume (arms.ts) then resumes via resumeWithVerification (which resumes AND verifies on
|
|
339
|
+
// completion). The initial TaskResult is shaped as a VerificationResult placeholder — no verdict until the
|
|
340
|
+
// resume completes; the objective oracle (runOracle) is the measure regardless.
|
|
214
341
|
runWithVerificationSup: async (implSpec) => {
|
|
215
342
|
const { runner } = await ensureWorker();
|
|
216
343
|
const result = await runner.runTask(toSupTaskSpec(baseSpec, implSpec, trap));
|
|
344
|
+
// 🔴 Map each durable-pause status to its OWN unverifiedReason (review MED): driveSupSuspendResume routes
|
|
345
|
+
// tool-approval (suspended → policy_ask) vs plan/dry-run review (needs_review → plan_review/dry_run_review) by
|
|
346
|
+
// this reason. Collapsing needs_review→"suspended" would send a plan-review gate down the tool-approval branch
|
|
347
|
+
// (bindingFromCheckpoint fails → the loop stops without resuming). Current firm traps don't hit a first-leg
|
|
348
|
+
// plan-review, but the driver advertises support for it.
|
|
217
349
|
const unverifiedReason = result.status === "needs_review" ? "needs_review" : result.status === "suspended" ? "suspended" : "no_verdict";
|
|
218
350
|
return { ...result, verification: { verdict: "unverified", unverifiedReason, rounds: 0, findings: [] } };
|
|
219
351
|
},
|
|
352
|
+
// ── SUP resume: resume the durable-suspended impl AND verify on completion ──
|
|
220
353
|
resumeWithVerification: async (token, outcome, implSpec) => {
|
|
221
354
|
const { runner } = await ensureWorker();
|
|
222
355
|
return resumeWithVerification(runner, token, outcome, toSupTaskSpec(baseSpec, implSpec, trap), implSpec.objective, { maxRounds: rt.maxRounds ?? 2 });
|
|
223
356
|
},
|
|
357
|
+
// ── SUP repair leg: the SAFE-tier self-repair loop. workerEnv IS wired (corr #3 — the §5.1 identity check
|
|
358
|
+
// is LIVE); the grader is the DISTINCT grader sandbox with the worker tree transferred in. ──
|
|
224
359
|
runRepairLoop: async (implSpec) => {
|
|
225
360
|
const { env: worker, runner } = await ensureWorker();
|
|
226
361
|
const grader = await ensureGraderWithWorkerTree();
|
|
362
|
+
// 🔴 (review #4) RE-SYNC the worker tree into the grader BEFORE EACH attempt's grading — the repair loop grades
|
|
363
|
+
// an EVOLVING worker tree once per attempt; the memoized one-shot transfer (correct for the non-repair
|
|
364
|
+
// single-grade path) would freeze the grader at the attempt-1 snapshot and a later fix would never be seen.
|
|
227
365
|
const oracle = makeRepairOracle({
|
|
228
366
|
transport: graderTransport(grader),
|
|
229
367
|
workerEnv: worker,
|
|
230
368
|
task: oracleTaskFromTrap(trap),
|
|
231
369
|
reSyncGraderTree: async () => {
|
|
232
|
-
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
370
|
+
state.shas = await transferWorkerTreeToGrader(worker, grader); // re-extract evolving worktree + refresh shas
|
|
233
371
|
},
|
|
234
372
|
});
|
|
235
373
|
return runRepairLoop(runner, toSupTaskSpec(baseSpec, implSpec, trap), {
|
|
236
374
|
oracle,
|
|
237
|
-
graderEnv: grader,
|
|
238
|
-
workerEnv: worker,
|
|
375
|
+
graderEnv: grader, // the DISTINCT grader env (assertDistinctEnvs ran at provision)
|
|
376
|
+
workerEnv: worker, // 🔴 corr #3 — wired so the §5.1 identity check runs (never skipped)
|
|
239
377
|
maxAttempts: 2,
|
|
240
378
|
});
|
|
241
379
|
},
|
|
380
|
+
// ── SUP: read the suspend's pending record (boundCallId/boundInputHash echoed VERBATIM — corr #2 / TOCTOU) ──
|
|
242
381
|
getCheckpoint: async (store, token, _scope) => {
|
|
243
382
|
return store.get(token);
|
|
244
383
|
},
|
|
384
|
+
// ── TEAM: the leader orchestrator via createLeaderRunner with budget-stamped workers. The leader integrates +
|
|
385
|
+
// PUSHES to a per-cell durable remote (git daemon on the CONTROL PLANE). On a DELIVERED run we bundle that
|
|
386
|
+
// integrated tree ON THE CONTROL PLANE and stash it as state.teamBundle; ensureGraderWithWorkerTree then seeds
|
|
387
|
+
// the GRADER from it directly (the worker stays the empty-base distinct env). If the integrated tree cannot be
|
|
388
|
+
// captured, runLeaderForTrap returns infraFailed (EXCLUDED, never a fabricated uniform loss). ──
|
|
245
389
|
runLeaderTask: async () => {
|
|
390
|
+
// 🔴 NETWORK ISOLATION (firm-v1/C4 drill): the leader's git daemon serves git://127.0.0.1:<port> on the CONTROL
|
|
391
|
+
// PLANE; the E2B sandboxes are network-isolated → cloning git://127.0.0.1 from INSIDE E2B hits the sandbox's own
|
|
392
|
+
// localhost ("not a git repository"). FIX: clone+bundle the integrated ref HERE on the control plane, stash the
|
|
393
|
+
// base64 bundle (+ its base hash) in state; the grader-import path (importBundleB64ToGrader via writeFile, the
|
|
394
|
+
// PROVEN control-plane↔E2B-grader transport) ships it into the grader. We never touch the E2B worker for this.
|
|
246
395
|
const captureIntegratedTreeToBundle = async (remoteUrl, targetRef) => {
|
|
247
396
|
const { execFileSync } = await import("node:child_process");
|
|
248
397
|
const { mkdtempSync, readFileSync, rmSync } = await import("node:fs");
|
|
@@ -260,19 +409,25 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
260
409
|
console.error(`[S1_DEBUG_IMPORT] cp clone --branch ${branch} failed: ${e1.stderr?.toString().slice(-200)}; retrying default`);
|
|
261
410
|
execFileSync("git", ["clone", "-q", remoteUrl, cloneDir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
262
411
|
}
|
|
412
|
+
// The integrated repo's root commit = the grader's s1-base (HEAD = the leader's merge commit, advanced past it).
|
|
263
413
|
const baseHash = execFileSync("git", ["-C", cloneDir, "rev-list", "--max-parents=0", "HEAD"]).toString().trim().split("\n").pop().trim();
|
|
264
414
|
const head = execFileSync("git", ["-C", cloneDir, "rev-parse", "HEAD"]).toString().trim();
|
|
265
415
|
if (!/^[0-9a-f]{40}$/.test(baseHash) || head === baseHash) {
|
|
266
416
|
if (process.env.S1_DEBUG_GIT)
|
|
267
417
|
console.error(`[S1_DEBUG_IMPORT] cp integrated tree not delivered: head=${head} base=${baseHash}`);
|
|
268
|
-
return false;
|
|
418
|
+
return false; // no advance past base ⇒ leader didn't deliver ⇒ infra-failed (NEVER a fake loss)
|
|
269
419
|
}
|
|
270
420
|
const bundlePath = join(tmp, "team.bundle");
|
|
421
|
+
// 🔴 git archive HEAD = the integrated WORKTREE as a tar (no .git) — the grader tar -x's plain files, never
|
|
422
|
+
// git clone (E2B grader-clone heisenbug + Kata virtiofs). delivered = head≠base from the shas computed here
|
|
423
|
+
// on the control plane (where git works). (Was: `git bundle` + grader clone — that hit both backends' git
|
|
424
|
+
// failures.) The single-revision HEAD bundle comment kept for history; we now ship a worktree tar instead.
|
|
425
|
+
// is tagged explicitly on the grader side, so delivered = HEAD≠base still resolves).
|
|
271
426
|
execFileSync("git", ["-C", cloneDir, "archive", "--format=tar", "-o", bundlePath, "HEAD"], { stdio: ["ignore", "ignore", "pipe"] });
|
|
272
|
-
const buffer = readFileSync(bundlePath);
|
|
427
|
+
const buffer = readFileSync(bundlePath); // RAW tar bytes — shipped to the grader as BINARY + tar -x'd (no git)
|
|
273
428
|
if (process.env.S1_DEBUG_GIT)
|
|
274
429
|
console.error(`[S1_DEBUG_IMPORT] cp integrated head=${head} base=${baseHash} tar bytes=${buffer.length}`);
|
|
275
|
-
state.teamBundle = { buffer, head, base: baseHash };
|
|
430
|
+
state.teamBundle = { buffer, head, base: baseHash }; // consumed by ensureGraderWithWorkerTree (tar -x, no git)
|
|
276
431
|
return true;
|
|
277
432
|
}
|
|
278
433
|
catch (e) {
|
|
@@ -286,16 +441,28 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
286
441
|
};
|
|
287
442
|
return runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, captureIntegratedTreeToBundle);
|
|
288
443
|
},
|
|
444
|
+
// ── The hidden objective oracle (the measure), graded in the DISTINCT grader env ──
|
|
289
445
|
runOracle: () => runOracle(false),
|
|
446
|
+
// 🔴 runCounterfactualOracle is DELIBERATELY OMITTED (it is OPTIONAL in ProfileDeps). The honest "no counterfactual"
|
|
447
|
+
// path: buildCounterfactual returns undefined → the metric tool records UNVERIFIED-WITHHELD (NO avoided-loss
|
|
448
|
+
// credit), the documented no-fake-credit choice (README / row.ts). The previous `runCounterfactualOracle:
|
|
449
|
+
// runOracle` self-alias re-graded the IDENTICAL post-gate tree, so withoutInterventionTrulyCorrect ALWAYS
|
|
450
|
+
// equaled withInterventionTrulyCorrect → every withhold auto-credited CORRECTLY-WITHHELD (withholdPrecision a
|
|
451
|
+
// tautological 1.0); for the SUP tool-deny path the deny is a REAL durable suspend that blocked the commit, so
|
|
452
|
+
// re-grading the same blocked tree is NOT an ablation. A real ablation (re-run the SAME (trap,seed) with the
|
|
453
|
+
// gate DISABLED into a FRESH worker, grade THAT in a separate grader) is the only thing that makes
|
|
454
|
+
// INCORRECTLY-WITHHELD reachable — TODO; until it lands we honestly omit rather than manufacture credit.
|
|
290
455
|
};
|
|
291
456
|
const dispose = async () => {
|
|
292
457
|
await Promise.allSettled([state.worker?.destroy(), state.grader?.destroy()]);
|
|
293
458
|
};
|
|
294
459
|
return { deps, dispose };
|
|
295
460
|
}
|
|
461
|
+
/** Project a `SoloImplSpec` (budget already stamped by the harness) onto the bench base TaskSpec. */
|
|
296
462
|
function toTaskSpec(base, impl) {
|
|
297
463
|
return { ...base(impl.objective), maxTokens: impl.maxTokens, maxCostUsd: impl.maxCostUsd, limits: { ...impl.limits } };
|
|
298
464
|
}
|
|
465
|
+
/** Project a `SupImplSpec` onto the bench base TaskSpec PLUS the durable wiring (checkpointStore + ask policy). */
|
|
299
466
|
function toSupTaskSpec(base, impl, trap) {
|
|
300
467
|
const requireApproval = trap.gatedTools ?? ["Bash"];
|
|
301
468
|
const neverAuto = trap.neverAuto ?? [];
|
|
@@ -307,7 +474,29 @@ function toSupTaskSpec(base, impl, trap) {
|
|
|
307
474
|
onQuestion: QUESTION_AWAITS_RESUME,
|
|
308
475
|
};
|
|
309
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Run the leader (TEAM) for a trap via `createLeaderRunner`, then map its `LeaderResult` → `LeaderTaskOutcome` (the
|
|
479
|
+
* subset the harness needs for the COMPLETE TEAM cost + outcome). The leader runs its OWN integration sandbox + an
|
|
480
|
+
* objective hidden oracle (its `testCmd` over the trap's oracleSteps) and PUSHES the integrated tree to a per-cell
|
|
481
|
+
* durable remote. The harness then IMPORTS that integrated tree into state.worker (via `importIntegratedTreeToWorker`)
|
|
482
|
+
* so its `runOracle` independently re-grades the REAL integrated output in the DISTINCT grader (the trusted measure —
|
|
483
|
+
* the leader's own gate is NOT trusted as the numerator). Budget-stamped: per-worker maxCostUsd is bounded so
|
|
484
|
+
* Σworker ≤ the arm budget.
|
|
485
|
+
*
|
|
486
|
+
* 🔴 The integrated tree is the actual TEAM output. The durable remote is served over `git://127.0.0.1` by a local
|
|
487
|
+
* `git daemon` (the leader/wire.ts validator REJECTS `file://`; `git://` passes AND the Coordinator can push to
|
|
488
|
+
* it). After a delivered run the harness clones the pushed targetRef into state.worker; if that import fails (the
|
|
489
|
+
* leader never delivered, or no integrated head exists) the cell is `infraFailed:true` (EXCLUDED) — NEVER a
|
|
490
|
+
* fabricated uniform "delivered=false" loss for the whole TEAM column.
|
|
491
|
+
*
|
|
492
|
+
* 🔴 The leader's workers run on the E2B factory (each its OWN VM — isolation). A leader crash surfaces as
|
|
493
|
+
* `infraFailed:true` (EXCLUDED), never a scored loss.
|
|
494
|
+
*/
|
|
310
495
|
async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, importIntegratedTreeToWorker) {
|
|
496
|
+
// The TEAM arm needs a durable remote to integrate into. For S1 we serve a throwaway local bare git repo over
|
|
497
|
+
// `git://127.0.0.1:<port>` via `git daemon` so (a) the leader/wire.ts validator accepts the URL (it forbids
|
|
498
|
+
// file://) and (b) the Coordinator can clone+push it. 🔴 Needs `git` (incl. `git daemon`) on the control-plane
|
|
499
|
+
// PATH (deploy req, leader/wire.ts header).
|
|
311
500
|
const { mkdtempSync, rmSync, writeFileSync, mkdirSync } = await import("node:fs");
|
|
312
501
|
const { execFileSync, spawn } = await import("node:child_process");
|
|
313
502
|
const { tmpdir } = await import("node:os");
|
|
@@ -317,7 +506,9 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
317
506
|
const repoName = "team.git";
|
|
318
507
|
const remoteDir = join(baseDir, repoName);
|
|
319
508
|
execFileSync("git", ["init", "-q", "--bare", remoteDir]);
|
|
509
|
+
// Mark the bare repo daemon-exportable (git daemon refuses to serve a repo without this unless --export-all).
|
|
320
510
|
execFileSync("git", ["--git-dir", remoteDir, "config", "daemon.receivepack", "true"]);
|
|
511
|
+
// Pick a free localhost port for the daemon (bind:0 → OS-assigned → read it back).
|
|
321
512
|
const port = await new Promise((resolve, reject) => {
|
|
322
513
|
const srv = net.createServer();
|
|
323
514
|
srv.once("error", reject);
|
|
@@ -327,6 +518,8 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
327
518
|
srv.close(() => (p ? resolve(p) : reject(new Error("could not pick a free port"))));
|
|
328
519
|
});
|
|
329
520
|
});
|
|
521
|
+
// Start `git daemon` serving baseDir over 127.0.0.1:port with push enabled. The URL the leader receives is
|
|
522
|
+
// git://127.0.0.1:<port>/<repoName>.
|
|
330
523
|
const daemon = spawn("git", [
|
|
331
524
|
"daemon",
|
|
332
525
|
"--reuseaddr",
|
|
@@ -337,6 +530,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
337
530
|
"--enable=receive-pack",
|
|
338
531
|
remoteDir,
|
|
339
532
|
], { stdio: "ignore" });
|
|
533
|
+
// Give the daemon a moment to bind (poll the port until it accepts, up to ~3s).
|
|
340
534
|
const waitForPort = async () => {
|
|
341
535
|
for (let i = 0; i < 30; i++) {
|
|
342
536
|
const up = await new Promise((resolve) => {
|
|
@@ -355,13 +549,22 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
355
549
|
};
|
|
356
550
|
const remoteUrl = `git://127.0.0.1:${port}/${basename(remoteDir)}`;
|
|
357
551
|
const targetRef = "refs/heads/main";
|
|
552
|
+
// Budget-stamped workers (Σ ≤ arm budget). The leader splits the arm budget across ≤2 workers for C4.
|
|
553
|
+
// 🔴 LOAD-BEARING ON THE SEQUENTIAL DRIVER (run-firm.ts: `for (const cell of cells)` is strictly sequential,
|
|
554
|
+
// one runArm at a time). loadConfig()/leaderResourceConfig() read these knobs ONLY from process.env (no
|
|
555
|
+
// parameterized override seam exists today), so env-stamping is the only lever. If run-firm's loop is ever
|
|
556
|
+
// parallelized, two cells would race on shared process.env (cross-contaminating the per-worker budget — the
|
|
557
|
+
// §3.2 fairness root); thread the config explicitly (loadConfig override args + LeaderWireConfig fields) FIRST.
|
|
358
558
|
process.env.LEADER_ENABLED = "true";
|
|
359
559
|
process.env.LEADER_WORKER_BUDGET_USD = String((rt.maxCostUsd ?? 1.0) / 2);
|
|
360
|
-
process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2";
|
|
560
|
+
process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2"; // C4 = fan-out conflict → resolver
|
|
361
561
|
const run = createLeaderRunner({
|
|
362
562
|
brain, models, roles, pricing, e2bApiKey: rt.e2bApiKey, workspace: W,
|
|
363
563
|
...(process.env.S1_DEBUG_GIT ? { logger: { warn: (m, x) => console.error(`[S1_DEBUG_LEADER warn] ${m}`, x ? JSON.stringify(x).slice(0, 300) : ""), info: (m, x) => console.error(`[S1_DEBUG_LEADER info] ${m}`, x ? JSON.stringify(x).slice(0, 200) : "") } } : {}),
|
|
364
564
|
});
|
|
565
|
+
// The seed command (run in each worker + the integration sandbox): a fresh repo at base. For a hazard trap (C7)
|
|
566
|
+
// the seedFiles are written + committed INTO each worker's base (PRECIOUS sentinel + scratch) so the worker SEES
|
|
567
|
+
// them and may over-delete from its local view (search S1c fan-out hazard). Absent ⇒ an empty base.
|
|
365
568
|
const teamSeedWrite = (trap.seedFiles ?? [])
|
|
366
569
|
.map((f) => {
|
|
367
570
|
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
@@ -371,6 +574,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
371
574
|
.join("; ");
|
|
372
575
|
const teamSeedStep = trap.seedFiles && trap.seedFiles.length > 0 ? `${teamSeedWrite}; git add -A; ` : "";
|
|
373
576
|
const seedCmd = `rm -rf ${REPO}; mkdir -p ${REPO}; cd ${REPO}; git init -q; git config user.email s1@bench.local; git config user.name s1-bench; git config commit.gpgsign false; ${teamSeedStep}git commit -q --allow-empty -m base`;
|
|
577
|
+
// The integration testCmd = the trap's objective COMMAND oracle steps (the leader's hidden-oracle gate).
|
|
374
578
|
const testCmd = trap.oracle.oracleSteps.map((s) => s.command).join(" && ");
|
|
375
579
|
const oracleFiles = trap.oracle.hiddenTestFiles;
|
|
376
580
|
const killDaemon = () => {
|
|
@@ -378,6 +582,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
378
582
|
daemon.kill("SIGKILL");
|
|
379
583
|
}
|
|
380
584
|
catch {
|
|
585
|
+
/* already gone */
|
|
381
586
|
}
|
|
382
587
|
};
|
|
383
588
|
let res;
|
|
@@ -385,11 +590,20 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
385
590
|
if (!(await waitForPort())) {
|
|
386
591
|
return { ok: false, reports: [], infraFailed: true };
|
|
387
592
|
}
|
|
593
|
+
// 🔴 Seed the bare daemon repo's `main` with a REAL base commit + capture its sha (firm-v1/C4 dig — the deepest
|
|
594
|
+
// TEAM layer). The bare repo was EMPTY and baseSha was the literal "HEAD": the Coordinator (wire.ts) clones the
|
|
595
|
+
// durable remote then `git am`s the integrated patch and pushes `--force-with-lease=refs/heads/main:<baseSha>`.
|
|
596
|
+
// With an empty repo + a non-sha "HEAD" lease, the integrated head landed at root INTERMITTENTLY → my control-plane
|
|
597
|
+
// clone of main saw root-only (head==base) → TEAM was unmeasurable. A real base commit + the real base sha makes
|
|
598
|
+
// the Coordinator's am apply on a deterministic base and the lease exact → main = the integrated merge, always.
|
|
388
599
|
const seedDir = mkdtempSync(join(tmpdir(), "s1-team-seed-"));
|
|
389
600
|
execFileSync("git", ["clone", "-q", remoteDir, seedDir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
390
601
|
execFileSync("git", ["-C", seedDir, "config", "user.email", "s1@bench.local"]);
|
|
391
602
|
execFileSync("git", ["-C", seedDir, "config", "user.name", "s1-bench"]);
|
|
392
603
|
execFileSync("git", ["-C", seedDir, "config", "commit.gpgsign", "false"]);
|
|
604
|
+
// Hazard trap (C7): seed the durable base with the SAME files (PRECIOUS sentinel + scratch) so the merge starts
|
|
605
|
+
// from a tree CONTAINING the sentinel — a worker's over-delete then surfaces as a real deletion in the integrated
|
|
606
|
+
// tree (merge-result survival). Absent ⇒ empty base (C4 disjoint creates everything fresh).
|
|
393
607
|
for (const f of trap.seedFiles ?? []) {
|
|
394
608
|
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
395
609
|
const abs = join(seedDir, rel);
|
|
@@ -410,6 +624,10 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
410
624
|
testCmd,
|
|
411
625
|
seedCmd,
|
|
412
626
|
oracleFiles,
|
|
627
|
+
// Fan-out plan: the explicit per-worker subtask list lives on the TrapSpec (C4 disjoint modules, C7 fan-out
|
|
628
|
+
// hazard). The leader's planner REQUIRES disjoint file ownership (a same-file plan is rejected "not disjoint").
|
|
629
|
+
// Each worker gets ONLY its local objective; the oracle checks the integrated result. Traps without subtasks
|
|
630
|
+
// stay single (the router collapses).
|
|
413
631
|
...(trap.subtasks ? { subtasks: trap.subtasks } : {}),
|
|
414
632
|
});
|
|
415
633
|
}
|
|
@@ -422,6 +640,10 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
422
640
|
}
|
|
423
641
|
if (process.env.S1_DEBUG_GIT)
|
|
424
642
|
console.error(`[S1_DEBUG_LEADER ${trap.id}] ok=${res.ok} error=${JSON.stringify(res.error)} cancelled=${res.cancelled} merge=${JSON.stringify(res.merge)} repairTerminal=${res.repairTerminal} reports=${(res.reports ?? []).length} reportsDetail=${JSON.stringify((res.reports ?? []).map((r) => ({ w: r.workerId, ok: r.ok, err: r.error })))?.slice(0, 400)}`);
|
|
643
|
+
// 🔴 Import the leader's INTEGRATED, pushed tree into state.worker so runOracle grades the REAL TEAM output (not
|
|
644
|
+
// an empty repo). The push leg only ran if the leader integrated+pushed successfully (res.merge.ok). If the
|
|
645
|
+
// import fails (no integrated head — leader did not deliver), mark the cell infra-failed (EXCLUDED), NEVER a
|
|
646
|
+
// fabricated uniform delivered=false loss. The daemon must stay alive for this clone, then we reap it.
|
|
425
647
|
let imported = false;
|
|
426
648
|
const merged = res.merge?.ok === true;
|
|
427
649
|
try {
|
|
@@ -435,6 +657,9 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
435
657
|
killDaemon();
|
|
436
658
|
rmSync(baseDir, { recursive: true, force: true });
|
|
437
659
|
}
|
|
660
|
+
// The leader ran but its integrated tree could not be moved into the grader path → NOT measurable. Honest
|
|
661
|
+
// infra-failed (EXCLUDED), never a fabricated loss. (A leader that legitimately withheld — held the merge — is a
|
|
662
|
+
// DIFFERENT case handled below via res.merge/repairTerminal, where !merged with a withhold terminal is expected.)
|
|
438
663
|
if (!imported && merged) {
|
|
439
664
|
return { ok: false, reports: res.reports, infraFailed: true };
|
|
440
665
|
}
|
|
@@ -442,8 +667,21 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
442
667
|
ok: res.ok,
|
|
443
668
|
reports: res.reports,
|
|
444
669
|
...(res.merge ? { merge: res.merge } : {}),
|
|
670
|
+
// 🔴 (review HIGH finding) a leader integration-test gate that REJECTED the merge (res.merge.ok===false,
|
|
671
|
+
// phase==="test" — the post-merge oracle/test gate caught a bad integrated tree, e.g. C7's fan-out hazard
|
|
672
|
+
// deleted the sentinel) is an HONEST WITHHOLD (the leader held a bad delivery), NOT a plain not-delivered.
|
|
673
|
+
// Without this, arms.ts withheld=false → the row is mis-booked. Surfacing withheld:true makes arms classify
|
|
674
|
+
// UNVERIFIED-WITHHELD (no counterfactual wired ⇒ NO avoided-loss credit — honest, never DELIVERED-WRONG and
|
|
675
|
+
// never a fake CORRECTLY-WITHHELD; the worker DID execute the hazard, the leader just didn't ship it).
|
|
445
676
|
...(res.merge?.ok === false && res.merge.phase === "test" ? { withheld: true } : {}),
|
|
677
|
+
// 🔴 the repair terminal (when the single-agent repair loop ran) drives the TEAM withhold classification in
|
|
678
|
+
// arms.ts (candidate_only/gave_up/conflict → withhold; oracle.unprotected → infra-failed). Passed through.
|
|
446
679
|
...(res.repairTerminal ? { repairTerminal: res.repairTerminal } : {}),
|
|
680
|
+
// A leader that integrated+pushed → the integrated tree is now in state.worker (runOracle grades it). A leader
|
|
681
|
+
// that did NOT merge (held the merge / repair non-accepting terminal) leaves state.worker empty → runOracle
|
|
682
|
+
// reports delivered=false, which is the HONEST verdict for an un-delivered TEAM run (the withhold classification
|
|
683
|
+
// in arms.ts reads merge/repairTerminal, and the absent counterfactual → UNVERIFIED-WITHHELD, no fake credit).
|
|
684
|
+
// The leader does not surface a stamped per-worker budget split here; honest "not measured" (undefined).
|
|
447
685
|
};
|
|
448
686
|
}
|
|
449
687
|
//# sourceMappingURL=live-deps.js.map
|