@sema-agent/server 7.43.0 → 7.44.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/USAGE.md +18 -0
- package/dist/adoption/plan.js +31 -192
- package/dist/adoption/quiesce.js +3 -86
- package/dist/adoption/runner.js +3 -140
- package/dist/adoption/sql.js +0 -74
- package/dist/adoption/wire.js +0 -80
- package/dist/approval-ask-machine.js +0 -75
- package/dist/approval-card.js +0 -323
- package/dist/approval-deny-reasons.js +0 -42
- package/dist/approval-hmac.js +0 -35
- package/dist/approval-reconciler.js +8 -166
- package/dist/approval.js +4 -67
- package/dist/audit.js +1 -44
- package/dist/auth-bridge.js +4 -47
- package/dist/auth-keys.js +0 -23
- package/dist/bake-runner/main.js +4 -65
- package/dist/bake-runner/protocol.js +3 -58
- package/dist/bake-runner/runner.js +5 -91
- package/dist/bench/l8/artifact.js +2 -61
- package/dist/bench/l8/escape.js +0 -25
- package/dist/bench/l8/index.js +0 -14
- package/dist/bench/l8/probes.js +0 -60
- package/dist/bench/l8/run-probes.js +2 -45
- package/dist/bench/s1/arms.js +14 -189
- package/dist/bench/s1/live-deps.js +11 -253
- package/dist/bench/s1/oracle.js +1 -36
- package/dist/bench/s1/repair-oracle-adapter.js +0 -30
- package/dist/bench/s1/reviewer.js +0 -34
- package/dist/bench/s1/row.js +0 -62
- package/dist/bench/s1/run-firm.js +4 -70
- package/dist/bench/s1/runner-ctx.js +0 -40
- package/dist/bench/s1/tasks.js +0 -115
- package/dist/boot/adoption.js +0 -20
- package/dist/boot/budget-tracing.js +3 -55
- package/dist/boot/config-center.js +43 -551
- package/dist/boot/coordinators.js +1 -69
- package/dist/boot/crash-last.js +0 -18
- package/dist/boot/deferred-sandbox-path-env.js +3 -119
- package/dist/boot/execution-env.js +5 -171
- package/dist/boot/governance-seams.js +0 -92
- package/dist/boot/leader.js +0 -69
- package/dist/boot/limit-sync.js +0 -2
- package/dist/boot/memory-boundary.js +3 -91
- package/dist/boot/org-memory.js +1 -25
- package/dist/boot/parked-revive-gate.js +0 -150
- package/dist/boot/permission-rules-audit.js +1 -56
- package/dist/boot/reapers.js +15 -273
- package/dist/boot/resolve-spec.js +9 -768
- package/dist/boot/retention-lane.js +4 -87
- package/dist/boot/runner-deps.js +3 -297
- package/dist/boot/runtime-caps.js +0 -40
- package/dist/boot/session-faces.js +2 -133
- package/dist/boot/shutdown.js +9 -83
- package/dist/boot/side-query-lane.js +2 -137
- package/dist/boot/stores.js +15 -215
- package/dist/boot/task-list-lane.js +0 -18
- package/dist/boot/webfetch-summarize-lane.js +0 -47
- package/dist/boot/workflow-orchestration.js +3 -99
- package/dist/boot-reclaim.js +0 -20
- package/dist/bounded-session-map.js +0 -19
- package/dist/brain.js +2 -139
- package/dist/budget.js +9 -244
- package/dist/capabilities/builtin-tools.js +0 -3
- package/dist/capabilities/center-plugins.js +6 -51
- package/dist/capabilities/center-prompts.js +6 -71
- package/dist/capabilities/code-review-council.js +7 -40
- package/dist/capabilities/collab-workflows.js +1 -44
- package/dist/capabilities/hands-lane.js +0 -65
- package/dist/capabilities/memory-notice.js +0 -70
- package/dist/capabilities/prompt.js +0 -14
- package/dist/capabilities/prompts/code-review.js +0 -14
- package/dist/capabilities/prompts/identity.js +0 -6
- package/dist/capabilities/prompts/team.js +0 -4
- package/dist/capabilities/repo-tools.js +0 -34
- package/dist/capabilities/sandbox-file-send.js +3 -92
- package/dist/capabilities/scenarios.d.ts +0 -1
- package/dist/capabilities/scenarios.js +18 -279
- package/dist/capabilities/select-environment-tool.js +0 -32
- package/dist/capabilities/send-user-file-tool.js +2 -66
- package/dist/capabilities/skills.d.ts +1 -2
- package/dist/capabilities/skills.js +3 -21
- package/dist/capabilities/team.d.ts +3 -11
- package/dist/capabilities/team.js +3 -51
- package/dist/capabilities/tool-defer.js +0 -3
- package/dist/config-center/apply-effective.js +15 -330
- package/dist/config-center/apply-ledger.js +5 -38
- package/dist/config-center/facade.js +0 -41
- package/dist/config-center/hot-keys-registry.js +0 -20
- package/dist/config-center/http-client.js +2 -125
- package/dist/config-center/mcp-revocation.js +2 -34
- package/dist/config-center/read-face.js +0 -59
- package/dist/config-center/restart-signal.js +1 -85
- package/dist/config-center/skills-mcp.d.ts +1 -1
- package/dist/config-center/skills-mcp.js +9 -76
- package/dist/config-center/stage-limits.js +8 -35
- package/dist/config-invariants.js +0 -16
- package/dist/config-lkg.js +0 -42
- package/dist/config-provider.js +3 -186
- package/dist/config-types.js +0 -5
- package/dist/config.js +107 -1145
- package/dist/degenerate-instrument.js +3 -67
- package/dist/deployment-governance.js +0 -124
- package/dist/digest-form.js +0 -12
- package/dist/elicitation.js +3 -86
- package/dist/env-facts.js +7 -75
- package/dist/fleet/fleet-bus.js +34 -507
- package/dist/fleet/fleet-reconciler.js +9 -149
- package/dist/fleet/fleet-terminal-window.js +10 -178
- package/dist/fleet/subagent-tail-bus.js +3 -72
- package/dist/fleet-client.js +10 -70
- package/dist/fleet-lease.js +5 -79
- package/dist/git-api-kind.js +0 -3
- package/dist/governance-ask-marks.js +2 -78
- package/dist/hooks/branch-transcript.js +0 -74
- package/dist/hooks/cc-agent-hook-prompt.js +0 -29
- package/dist/hooks/cc-stop-prompt.js +1 -46
- package/dist/hooks/hook-llm.js +1 -53
- package/dist/hooks/hook-runner.js +20 -414
- package/dist/http/active-run-conflict.js +4 -129
- package/dist/http/cursor-fingerprint.d.ts +5 -0
- package/dist/http/cursor-fingerprint.js +5 -0
- package/dist/http/idempotency.js +0 -37
- package/dist/http/principal-gate.js +3 -40
- package/dist/http/route-ctx.js +0 -9
- package/dist/http/routes/a2a-serve.js +7 -319
- package/dist/http/routes/admin-config-refresh.js +0 -4
- package/dist/http/routes/admin-drain.js +0 -10
- package/dist/http/routes/adoption.js +1 -29
- package/dist/http/routes/agents-roster.js +1 -47
- package/dist/http/routes/approvals-assistant.js +32 -395
- package/dist/http/routes/attachments.js +4 -22
- package/dist/http/routes/capabilities.js +3 -420
- package/dist/http/routes/diagnostics.js +1 -81
- package/dist/http/routes/fleet.js +9 -185
- package/dist/http/routes/images.js +14 -239
- package/dist/http/routes/leader.js +0 -13
- package/dist/http/routes/memory-bundle.js +1 -61
- package/dist/http/routes/memory-policy.js +9 -99
- package/dist/http/routes/notify-wake.js +3 -37
- package/dist/http/routes/observability.js +2 -19
- package/dist/http/routes/retention-ops.js +2 -34
- package/dist/http/routes/rules.js +1 -93
- package/dist/http/routes/runs.js +64 -873
- package/dist/http/routes/session-sync.js +19 -258
- package/dist/http/routes/sessions-list.js +17 -43
- package/dist/http/routes/sessions.js +34 -226
- package/dist/http/routes/shared-memory.js +5 -36
- package/dist/http/routes/side-query.js +1 -87
- package/dist/http/routes/tasks.js +52 -722
- package/dist/http/routes/trace-usage.js +32 -195
- package/dist/http/routes/workflows.js +19 -195
- package/dist/http/run-meta.js +0 -6
- package/dist/http/send.js +0 -32
- package/dist/http/server.js +92 -1597
- package/dist/http/sse-lifecycle.js +2 -13
- package/dist/http/sse-log.js +3 -48
- package/dist/http/tar.js +5 -21
- package/dist/http/verify-rounds.js +0 -5
- package/dist/http/wire-gate.js +0 -9
- package/dist/http/workspace-content.js +0 -10
- package/dist/images/bake-validate.js +1 -70
- package/dist/images/manifest.js +1 -6
- package/dist/index.js +0 -21
- package/dist/key-resolver.js +2 -17
- package/dist/leader/diffout.js +1 -20
- package/dist/leader/diffup.js +0 -47
- package/dist/leader/endpoint.js +2 -57
- package/dist/leader/fanout.js +3 -45
- package/dist/leader/grader-env-factory.js +3 -72
- package/dist/leader/leader.js +5 -156
- package/dist/leader/merge.js +8 -115
- package/dist/leader/planner.js +3 -54
- package/dist/leader/repair-oracle.js +1 -60
- package/dist/leader/repair-wire.js +2 -79
- package/dist/leader/wire.js +8 -307
- package/dist/lsp/e2b-bridge.js +4 -64
- package/dist/lsp/e2b-manager.js +6 -94
- package/dist/lsp/lsp-frames.js +0 -12
- package/dist/lsp/manager.js +4 -96
- package/dist/lsp/ws-transport.js +5 -55
- package/dist/lsp-evict.js +1 -15
- package/dist/main.js +57 -765
- package/dist/memory-bundle-engine.js +0 -55
- package/dist/memory-export.js +0 -4
- package/dist/memory-posture.js +1 -15
- package/dist/memory-scope.js +11 -148
- package/dist/memory-sync-client.js +2 -44
- package/dist/memory-sync.js +1 -80
- package/dist/model-select.js +3 -80
- package/dist/observability/cost-quota.js +1 -17
- package/dist/observability/cost-taxonomy.js +0 -34
- package/dist/observability/fail-open.js +7 -86
- package/dist/observability/logger.js +0 -6
- package/dist/observability/metrics.js +0 -94
- package/dist/observability/otel-exporter.js +3 -13
- package/dist/observability/principal-context.js +0 -9
- package/dist/observability/prompt-manifest.js +1 -37
- package/dist/observability/rate-limit.js +0 -4
- package/dist/observability/secret-env-scrub.js +2 -56
- package/dist/observability/tool-trace.js +1 -70
- package/dist/orchestration/hardened-vm-runner.js +4 -118
- package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
- package/dist/orchestration/hardened-vm-worker.js +0 -27
- package/dist/orchestration/subagent-steer.js +1 -45
- package/dist/orchestration/workflow-agent-steer.js +1 -80
- package/dist/orchestration/workflow-completion-inbox.js +32 -285
- package/dist/orchestration/workflow-notify-journal.js +16 -259
- package/dist/org-memory-admission.js +3 -47
- package/dist/parent-watch.js +2 -48
- package/dist/parked-decide.js +1 -109
- package/dist/per-task-image.js +0 -57
- package/dist/plan-cache-probe.js +3 -27
- package/dist/plugins/adoption-log-sql.js +2 -119
- package/dist/plugins/approval-ask-store-memory.js +3 -38
- package/dist/plugins/approval-ask-store-sql.js +6 -188
- package/dist/plugins/approval-exemption-store.js +2 -28
- package/dist/plugins/background-agent-store-sql.js +4 -105
- package/dist/plugins/background-shell-support.js +14 -122
- package/dist/plugins/blob-backend.js +6 -169
- package/dist/plugins/breaker-state-sql.js +8 -46
- package/dist/plugins/caching-session-store.js +4 -106
- package/dist/plugins/checkpoint-store-sql.js +18 -505
- package/dist/plugins/e2b-orphan-reclaim.js +0 -45
- package/dist/plugins/file-outcome-sink.js +0 -9
- package/dist/plugins/file-resume-anchor-store.js +4 -43
- package/dist/plugins/file-run-store.js +26 -364
- package/dist/plugins/file-snapshot-store-sql.js +10 -181
- package/dist/plugins/fork-routing-session-store.js +8 -111
- package/dist/plugins/host-platform.js +2 -91
- package/dist/plugins/image-bake-store-sql.js +7 -250
- package/dist/plugins/image-index-sql.js +4 -123
- package/dist/plugins/k8s-bg-scripts.js +4 -88
- package/dist/plugins/k8s-exec-protocol.js +0 -41
- package/dist/plugins/leader-run-store-sql.js +0 -101
- package/dist/plugins/local-checkpoint-store.js +8 -128
- package/dist/plugins/local-session-store.js +34 -296
- package/dist/plugins/local-task-attachment-store.js +2 -16
- package/dist/plugins/mailbox-store-sql.js +8 -65
- package/dist/plugins/memory-embedder-fingerprint.js +5 -166
- package/dist/plugins/memory-embedder.js +4 -70
- package/dist/plugins/memory-engine-pg.js +6 -170
- package/dist/plugins/memory-engine-tidb.js +7 -155
- package/dist/plugins/memory-engine-vector-util.js +0 -10
- package/dist/plugins/memory-key-guards.js +0 -34
- package/dist/plugins/memory-origin-law.js +0 -187
- package/dist/plugins/memory-resume-anchor-store.js +0 -17
- package/dist/plugins/memory-run-store.js +12 -89
- package/dist/plugins/memory-session-policy-store.js +0 -17
- package/dist/plugins/memory-sync-store-pg.js +4 -49
- package/dist/plugins/memory-sync-store-tidb.js +3 -35
- package/dist/plugins/outcome-ledger-sql.js +3 -97
- package/dist/plugins/permission-rule-store-file.js +5 -133
- package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
- package/dist/plugins/permission-rule-store-sql.js +50 -307
- package/dist/plugins/pg-cost-quota.js +0 -7
- package/dist/plugins/pg-pool.js +0 -92
- package/dist/plugins/pg-rate-limiter.js +2 -13
- package/dist/plugins/pg-safe-json.js +4 -40
- package/dist/plugins/pg-session-storage.js +25 -189
- package/dist/plugins/posix-shell-fs.js +1 -31
- package/dist/plugins/remote-env-adb.js +12 -101
- package/dist/plugins/remote-env-e2b.js +40 -371
- package/dist/plugins/remote-env-file-error.js +0 -37
- package/dist/plugins/remote-env-host.js +63 -483
- package/dist/plugins/remote-env-k8s.js +32 -326
- package/dist/plugins/remote-env-local-docker.js +24 -157
- package/dist/plugins/remote-env-ssh.js +20 -128
- package/dist/plugins/remote-scratchpad.js +2 -32
- package/dist/plugins/remote-shell.js +1 -32
- package/dist/plugins/resume-anchor-store-sql.js +0 -11
- package/dist/plugins/retention-lane-store-sql.js +0 -108
- package/dist/plugins/retention-store-sql.js +4 -383
- package/dist/plugins/roster-store-sql.js +0 -55
- package/dist/plugins/run-store-sql.js +14 -251
- package/dist/plugins/s3-presign.js +2 -49
- package/dist/plugins/scheduler-support.js +3 -80
- package/dist/plugins/send-file-ledger.js +4 -53
- package/dist/plugins/send-user-file.js +4 -94
- package/dist/plugins/session-placement.js +1 -89
- package/dist/plugins/session-policy-store-sql.js +3 -81
- package/dist/plugins/session-store.js +0 -57
- package/dist/plugins/shared-memory-store-sql.js +4 -167
- package/dist/plugins/sql-driver.js +0 -17
- package/dist/plugins/sql-errors.js +0 -7
- package/dist/plugins/sql-escape.js +0 -8
- package/dist/plugins/sql-row-helpers.js +0 -25
- package/dist/plugins/store-backend.js +42 -222
- package/dist/plugins/store-contracts.js +2 -46
- package/dist/plugins/task-attachment-store.js +3 -49
- package/dist/plugins/task-list-store-sql.js +0 -79
- package/dist/plugins/tidb-cost-quota.js +1 -4
- package/dist/plugins/tidb-pool.js +1 -207
- package/dist/plugins/tidb-rate-limiter.js +3 -9
- package/dist/plugins/tidb-session-storage.js +4 -70
- package/dist/plugins/tidb-session-store.js +19 -341
- package/dist/plugins/tool-result-store-sql.js +4 -179
- package/dist/plugins/usage-window-store-sql.js +0 -8
- package/dist/plugins/web-search.js +10 -132
- package/dist/plugins/workflow-journal-store-sql.js +2 -58
- package/dist/plugins/workflow-run-store-sql.js +6 -91
- package/dist/plugins/worktree-isolation.js +6 -126
- package/dist/plugins/write-behind-counter.js +16 -75
- package/dist/principal-jwt.js +5 -60
- package/dist/project-memory.js +15 -146
- package/dist/prompts-domain-validate.js +1 -51
- package/dist/question.js +2 -111
- package/dist/resource-suspend.js +0 -18
- package/dist/router/route-orchestration.js +0 -77
- package/dist/rules-consent.d.ts +44 -5
- package/dist/rules-consent.js +75 -215
- package/dist/run-local.js +14 -381
- package/dist/runs.js +29 -617
- package/dist/runtime-caps-resolver.js +6 -132
- package/dist/runtime-governance.js +1 -232
- package/dist/sandbox-pkg-source.js +0 -37
- package/dist/sealed-key.js +3 -68
- package/dist/security.js +6 -291
- package/dist/session-leaf-bus.js +0 -32
- package/dist/session-sync-content.js +1 -69
- package/dist/session-sync-kernel.js +3 -60
- package/dist/session-sync.js +3 -66
- package/dist/session-titler.js +7 -41
- package/dist/session-watch.js +9 -73
- package/dist/shared-memory-scope-authorizer.js +0 -18
- package/dist/sighup-idle.js +1 -12
- package/dist/spec-fields.js +4 -143
- package/dist/store-live-probe.js +3 -49
- package/dist/task-a2a.js +1 -126
- package/dist/task-cwd.js +1 -103
- package/dist/task-mcp.js +1 -89
- package/dist/task-settings.js +10 -300
- package/dist/task-workflow.js +8 -75
- package/dist/tool-approval.d.ts +28 -1
- package/dist/tool-approval.js +70 -1430
- package/dist/trace/artifacts.js +5 -20
- package/dist/trace/engine-notice-wire.js +6 -138
- package/dist/trace/ledger-sink.js +7 -96
- package/dist/trace/project.js +4 -448
- package/dist/trace/redact.js +9 -77
- package/dist/turn-activity.js +1 -27
- package/dist/usage-analytics.js +4 -34
- package/dist/wall-clock-jump-guard.js +1 -68
- package/package.json +3 -3
- package/dist/capabilities/scenario-alias.d.ts +0 -27
- package/dist/capabilities/scenario-alias.js +0 -61
|
@@ -1,39 +1,3 @@
|
|
|
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
|
-
*/
|
|
37
1
|
import { Runner, runWithVerification, resumeWithVerification, runRepairLoop, combinePolicies, createDurableQuestionPolicy, QUESTION_AWAITS_RESUME, } from "@sema-agent/core";
|
|
38
2
|
import { loadConfig } from "../../config.js";
|
|
39
3
|
import { createBrain } from "../../brain.js";
|
|
@@ -44,23 +8,14 @@ import { createLeaderRunner } from "../../leader/wire.js";
|
|
|
44
8
|
import { runOracle as runStandaloneOracle } from "./oracle.js";
|
|
45
9
|
import { makeRepairOracle } from "./repair-oracle-adapter.js";
|
|
46
10
|
import { assertDistinctEnvs } from "./runner-ctx.js";
|
|
47
|
-
/** The worker/grader workspace root inside each E2B VM. */
|
|
48
11
|
const W = "/home/user";
|
|
49
|
-
/** The repo dir inside each VM where the worker's tree lives + the grader checks out. */
|
|
50
12
|
const REPO = `${W}/repo`;
|
|
51
|
-
/** The grader's base ref for the `delivered` (HEAD advanced past base) signal. The seed commits an empty base. */
|
|
52
13
|
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). */
|
|
56
14
|
export function liveRuntimeConfigFromEnv(env = process.env) {
|
|
57
15
|
const e2bApiKey = env.E2B_API_KEY;
|
|
58
16
|
const deepseekApiKey = env.DEEPSEEK_API_KEY;
|
|
59
17
|
if (!e2bApiKey || !deepseekApiKey)
|
|
60
18
|
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.
|
|
64
19
|
const costInput = Number(env.MODEL_COST_INPUT ?? "");
|
|
65
20
|
const costOutput = Number(env.MODEL_COST_OUTPUT ?? "");
|
|
66
21
|
if (!(costInput > 0) || !(costOutput > 0))
|
|
@@ -82,28 +37,20 @@ export function liveRuntimeConfigFromEnv(env = process.env) {
|
|
|
82
37
|
...(Number(env.MODEL_COST_CACHE_WRITE ?? "") > 0 ? { costCacheWrite: Number(env.MODEL_COST_CACHE_WRITE) } : {}),
|
|
83
38
|
};
|
|
84
39
|
}
|
|
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. */
|
|
87
40
|
function buildBrainIngredients(rt) {
|
|
88
|
-
// Point the loader at DeepSeek (mirrors the live tests' env stamping) then build the brain/pricing.
|
|
89
41
|
process.env.MODEL_GATEWAY_BASEURL = rt.gatewayBaseUrl;
|
|
90
42
|
process.env.MODEL_ID = rt.modelId;
|
|
91
43
|
process.env.MODEL_API_KEY = rt.deepseekApiKey;
|
|
92
44
|
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.
|
|
95
45
|
process.env.MODEL_COST_INPUT = String(rt.costInput);
|
|
96
46
|
process.env.MODEL_COST_OUTPUT = String(rt.costOutput);
|
|
97
47
|
if (rt.costCacheRead != null)
|
|
98
48
|
process.env.MODEL_COST_CACHE_READ = String(rt.costCacheRead);
|
|
99
49
|
if (rt.costCacheWrite != null)
|
|
100
50
|
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.
|
|
103
51
|
const config = loadConfig();
|
|
104
52
|
const brain = createBrain(config, {});
|
|
105
53
|
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.
|
|
107
54
|
const p = pricing[rt.modelId];
|
|
108
55
|
if (!p || ((p.inputPer1M ?? 0) === 0 && (p.outputPer1M ?? 0) === 0)) {
|
|
109
56
|
throw new Error(`s1 live: zero pricing for ${rt.modelId} — C1 cost axis would be a fabricated $0 (set MODEL_COST_INPUT/OUTPUT)`);
|
|
@@ -116,7 +63,6 @@ const sh = (env) => async (cmd) => {
|
|
|
116
63
|
throw new Error(`s1 transport: ${r.error.message}`);
|
|
117
64
|
return { code: r.value.exitCode, out: (r.value.stdout + r.value.stderr).trim() };
|
|
118
65
|
};
|
|
119
|
-
/** Provision + connect a fresh E2B sandbox with an empty git repo seeded at the `s1-base` ref. */
|
|
120
66
|
async function provisionSandbox(rt, role, cellId) {
|
|
121
67
|
const env = new RemoteContainerExecutionEnv({
|
|
122
68
|
apiKey: rt.e2bApiKey,
|
|
@@ -129,14 +75,10 @@ async function provisionSandbox(rt, role, cellId) {
|
|
|
129
75
|
throw new Error(`s1 ${role} sandbox connect failed (${cellId}): ${c.error.message}`);
|
|
130
76
|
return env;
|
|
131
77
|
}
|
|
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. */
|
|
135
78
|
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.
|
|
137
79
|
const writeCmds = (seedFiles ?? [])
|
|
138
80
|
.map((f) => {
|
|
139
|
-
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
81
|
+
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
140
82
|
const b64 = Buffer.from(f.content, "utf8").toString("base64");
|
|
141
83
|
return `mkdir -p "$(dirname '${rel}')" 2>/dev/null; printf %s '${b64}' | base64 -d > '${rel}'`;
|
|
142
84
|
})
|
|
@@ -149,18 +91,7 @@ async function seedBaseRepo(env, seedFiles) {
|
|
|
149
91
|
if (r.code !== 0)
|
|
150
92
|
throw new Error(`s1 seed base repo failed: ${r.out.slice(-400)}`);
|
|
151
93
|
}
|
|
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
|
-
*/
|
|
158
94
|
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).
|
|
164
95
|
const headProbe = await sh(worker)(`cd ${REPO} && git rev-parse HEAD`);
|
|
165
96
|
const baseProbe = await sh(worker)(`cd ${REPO} && git rev-parse ${BASE_REF}`);
|
|
166
97
|
const head = headProbe.out.trim();
|
|
@@ -169,14 +100,12 @@ async function transferWorkerTreeToGrader(worker, grader) {
|
|
|
169
100
|
throw new Error(`s1 worker HEAD unresolved: ${headProbe.out.slice(-200)}`);
|
|
170
101
|
if (!/^[0-9a-f]{40}$/.test(base))
|
|
171
102
|
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.
|
|
173
103
|
const arch = await sh(worker)(`cd ${REPO} && git archive --format=tar HEAD | base64 -w0`);
|
|
174
104
|
if (arch.code !== 0)
|
|
175
105
|
throw new Error(`s1 worker archive failed: ${arch.out.slice(-400)}`);
|
|
176
106
|
const buf = Buffer.from(arch.out.trim(), "base64");
|
|
177
107
|
if (buf.length === 0)
|
|
178
108
|
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.
|
|
180
109
|
const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(buf));
|
|
181
110
|
if (!wr.ok)
|
|
182
111
|
throw new Error(`s1 grader tar write failed: ${wr.error.message}`);
|
|
@@ -187,47 +116,23 @@ async function transferWorkerTreeToGrader(worker, grader) {
|
|
|
187
116
|
console.error(`[S1_DEBUG_TAR] head=${head.slice(0, 8)} base=${base.slice(0, 8)} tarBytes=${buf.length} ${ext.out.slice(-60)}`);
|
|
188
117
|
return { head, base };
|
|
189
118
|
}
|
|
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
|
-
*/
|
|
197
119
|
async function importBundleB64ToGrader(grader, bundleB64, baseHash) {
|
|
198
120
|
if (!/^[0-9a-f]{40}$/.test(baseHash))
|
|
199
121
|
throw new Error(`s1 grader import: invalid base hash ${JSON.stringify(baseHash)}`);
|
|
200
122
|
const wr = await grader.writeFile(`/tmp/s1.bundle.b64`, bundleB64);
|
|
201
123
|
if (!wr.ok)
|
|
202
124
|
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.
|
|
207
125
|
const imp = await sh(grader)(`set -e; base64 -d /tmp/s1.bundle.b64 > /tmp/s1.bundle; test -s /tmp/s1.bundle; rm -rf ${REPO}; ` +
|
|
208
126
|
`git clone -q /tmp/s1.bundle ${REPO}; cd ${REPO}; ` +
|
|
209
127
|
`git config user.email s1@bench.local; git config user.name s1-bench; ` +
|
|
210
128
|
`git tag -f ${BASE_REF} ${baseHash}`);
|
|
211
129
|
if (imp.code !== 0)
|
|
212
130
|
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).
|
|
215
131
|
const verify = await sh(grader)(`cd ${REPO} && echo "BASE=$(git rev-parse ${BASE_REF}) HEAD=$(git rev-parse HEAD)"`);
|
|
216
132
|
if (!verify.out.includes(`BASE=${baseHash}`))
|
|
217
133
|
throw new Error(`s1 grader base mismatch: ${verify.out.slice(-200)} expected BASE=${baseHash}`);
|
|
218
134
|
}
|
|
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
|
-
*/
|
|
226
135
|
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.
|
|
231
136
|
if (!/^[0-9a-f]{40}$/.test(shas.head) || !/^[0-9a-f]{40}$/.test(shas.base))
|
|
232
137
|
throw new Error(`s1 grader import: invalid shas ${JSON.stringify(shas)}`);
|
|
233
138
|
const wr = await grader.writeFile(`/tmp/s1-wt.tar`, new Uint8Array(tarBuffer));
|
|
@@ -240,11 +145,9 @@ async function importBundleBinaryToGrader(grader, tarBuffer, shas) {
|
|
|
240
145
|
console.error(`[S1_DEBUG_TAR team] head=${shas.head.slice(0, 8)} base=${shas.base.slice(0, 8)} ${ext.out.slice(-60)}`);
|
|
241
146
|
return shas;
|
|
242
147
|
}
|
|
243
|
-
/** Build the OracleTask the standalone oracle consumes from a trap (stamps graderRepoDir + baseRef). */
|
|
244
148
|
function oracleTaskFromTrap(trap) {
|
|
245
149
|
return { ...trap.oracle, graderRepoDir: REPO, baseRef: BASE_REF };
|
|
246
150
|
}
|
|
247
|
-
/** A GraderTransport bound to a grader sandbox (clone/checkout via exec; hidden-test writes via writeFile). */
|
|
248
151
|
function graderTransport(grader) {
|
|
249
152
|
return {
|
|
250
153
|
exec: async (command) => {
|
|
@@ -260,21 +163,9 @@ function graderTransport(grader) {
|
|
|
260
163
|
},
|
|
261
164
|
};
|
|
262
165
|
}
|
|
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
|
-
*/
|
|
273
166
|
export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
274
167
|
const { brain, models, roles, pricing } = buildBrainIngredients(rt);
|
|
275
168
|
const baseSpec = benchBaseSpec(rt, cellId);
|
|
276
|
-
// Lazily-provisioned, memoized per-cell sandboxes (so a cell that never runs a seam pays zero VM cost; a seam
|
|
277
|
-
// that throws still leaves them on `state` so dispose() reaps them).
|
|
278
169
|
const state = {};
|
|
279
170
|
const ensureWorker = async () => {
|
|
280
171
|
if (!state.worker) {
|
|
@@ -284,15 +175,12 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
284
175
|
}
|
|
285
176
|
return { env: state.worker, runner: state.runner };
|
|
286
177
|
};
|
|
287
|
-
/** Provision the DISTINCT grader, transfer the worker's committed tree in. Memoized (graded once per cell). */
|
|
288
178
|
const ensureGraderWithWorkerTree = async () => {
|
|
289
179
|
const { env: worker } = await ensureWorker();
|
|
290
180
|
if (!state.grader) {
|
|
291
181
|
state.grader = await provisionSandbox(rt, "grader", cellId);
|
|
292
|
-
assertDistinctEnvs(worker, state.grader);
|
|
293
|
-
// No grader seedBaseRepo: the grader holds a tar-extracted worktree (no .git at all), so it needs no git identity.
|
|
182
|
+
assertDistinctEnvs(worker, state.grader);
|
|
294
183
|
if (state.teamBundle) {
|
|
295
|
-
// TEAM: extract the control-plane-archived integrated worktree into the grader (tar, no git — same dodge).
|
|
296
184
|
state.shas = await importBundleBinaryToGrader(state.grader, state.teamBundle.buffer, { head: state.teamBundle.head, base: state.teamBundle.base });
|
|
297
185
|
}
|
|
298
186
|
else {
|
|
@@ -301,91 +189,54 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
301
189
|
}
|
|
302
190
|
return state.grader;
|
|
303
191
|
};
|
|
304
|
-
/** Run the OBJECTIVE oracle in the DISTINCT grader env (the measure — runExecGate over real exit codes).
|
|
305
|
-
* @param reSyncWorkerTree when true, RE-TRANSFER the worker's committed tree into the (already-provisioned)
|
|
306
|
-
* grader before grading. The non-repair path grades a STABLE terminal tree once (memoized transfer is
|
|
307
|
-
* correct); the repair loop calls the oracle ONCE PER ATTEMPT against an EVOLVING worker tree, so it MUST
|
|
308
|
-
* re-sync or it would forever grade the frozen attempt-1 snapshot (the grader would never see a fix land). */
|
|
309
192
|
const runOracle = async (reSyncWorkerTree = false) => {
|
|
310
193
|
const { env: worker } = await ensureWorker();
|
|
311
194
|
const grader = await ensureGraderWithWorkerTree();
|
|
312
195
|
if (reSyncWorkerTree)
|
|
313
|
-
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
196
|
+
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
314
197
|
const task = { ...oracleTaskFromTrap(trap), ...(state.shas ? { deliveredShas: state.shas } : {}) };
|
|
315
198
|
const v = await runStandaloneOracle(grader, graderTransport(grader), worker, task);
|
|
316
199
|
if (process.env.S1_DEBUG_GIT)
|
|
317
200
|
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));
|
|
318
|
-
return v;
|
|
201
|
+
return v;
|
|
319
202
|
};
|
|
320
203
|
const deps = {
|
|
321
|
-
// ── SOLO: run the impl behind the verify→fix gate via the REAL core runWithVerification ──
|
|
322
204
|
runWithVerification: async (implSpec) => {
|
|
323
205
|
const { runner } = await ensureWorker();
|
|
324
206
|
return runWithVerification(runner, toTaskSpec(baseSpec, implSpec), { maxRounds: rt.maxRounds ?? 2 });
|
|
325
207
|
},
|
|
326
|
-
// ── SUP verify/durable path ──
|
|
327
|
-
// 🔴 durable suspend/resume is ONLY supported at the TOP-LEVEL runTask (core's mapNestedSuspend HARD boundary,
|
|
328
|
-
// design/45 §11 Q6 / design/80 D-B): the NESTED runWithVerification maps a durable pause to status:"failed"
|
|
329
|
-
// (UNEXPECTED_SUSPENDED), so the SUP HITL gate (gated bash → suspend) was ALWAYS infra-failed (caught by the
|
|
330
|
-
// firm-v1 N=1 all-paths smoke: C1/C2-SUP failed at turn 1, unverifiedReason="suspended", checkpointGate present).
|
|
331
|
-
// FIX: run the durable task at the TOP LEVEL so the suspend propagates as status:"suspended" + checkpointToken;
|
|
332
|
-
// driveSupSuspendResume (arms.ts) then resumes via resumeWithVerification (which resumes AND verifies on
|
|
333
|
-
// completion). The initial TaskResult is shaped as a VerificationResult placeholder — no verdict until the
|
|
334
|
-
// resume completes; the objective oracle (runOracle) is the measure regardless.
|
|
335
208
|
runWithVerificationSup: async (implSpec) => {
|
|
336
209
|
const { runner } = await ensureWorker();
|
|
337
210
|
const result = await runner.runTask(toSupTaskSpec(baseSpec, implSpec, trap));
|
|
338
|
-
// 🔴 Map each durable-pause status to its OWN unverifiedReason (review MED): driveSupSuspendResume routes
|
|
339
|
-
// tool-approval (suspended → policy_ask) vs plan/dry-run review (needs_review → plan_review/dry_run_review) by
|
|
340
|
-
// this reason. Collapsing needs_review→"suspended" would send a plan-review gate down the tool-approval branch
|
|
341
|
-
// (bindingFromCheckpoint fails → the loop stops without resuming). Current firm traps don't hit a first-leg
|
|
342
|
-
// plan-review, but the driver advertises support for it.
|
|
343
211
|
const unverifiedReason = result.status === "needs_review" ? "needs_review" : result.status === "suspended" ? "suspended" : "no_verdict";
|
|
344
212
|
return { ...result, verification: { verdict: "unverified", unverifiedReason, rounds: 0, findings: [] } };
|
|
345
213
|
},
|
|
346
|
-
// ── SUP resume: resume the durable-suspended impl AND verify on completion ──
|
|
347
214
|
resumeWithVerification: async (token, outcome, implSpec) => {
|
|
348
215
|
const { runner } = await ensureWorker();
|
|
349
216
|
return resumeWithVerification(runner, token, outcome, toSupTaskSpec(baseSpec, implSpec, trap), implSpec.objective, { maxRounds: rt.maxRounds ?? 2 });
|
|
350
217
|
},
|
|
351
|
-
// ── SUP repair leg: the SAFE-tier self-repair loop. workerEnv IS wired (corr #3 — the §5.1 identity check
|
|
352
|
-
// is LIVE); the grader is the DISTINCT grader sandbox with the worker tree transferred in. ──
|
|
353
218
|
runRepairLoop: async (implSpec) => {
|
|
354
219
|
const { env: worker, runner } = await ensureWorker();
|
|
355
220
|
const grader = await ensureGraderWithWorkerTree();
|
|
356
|
-
// 🔴 (review #4) RE-SYNC the worker tree into the grader BEFORE EACH attempt's grading — the repair loop grades
|
|
357
|
-
// an EVOLVING worker tree once per attempt; the memoized one-shot transfer (correct for the non-repair
|
|
358
|
-
// single-grade path) would freeze the grader at the attempt-1 snapshot and a later fix would never be seen.
|
|
359
221
|
const oracle = makeRepairOracle({
|
|
360
222
|
transport: graderTransport(grader),
|
|
361
223
|
workerEnv: worker,
|
|
362
224
|
task: oracleTaskFromTrap(trap),
|
|
363
225
|
reSyncGraderTree: async () => {
|
|
364
|
-
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
226
|
+
state.shas = await transferWorkerTreeToGrader(worker, grader);
|
|
365
227
|
},
|
|
366
228
|
});
|
|
367
229
|
return runRepairLoop(runner, toSupTaskSpec(baseSpec, implSpec, trap), {
|
|
368
230
|
oracle,
|
|
369
|
-
graderEnv: grader,
|
|
370
|
-
workerEnv: worker,
|
|
231
|
+
graderEnv: grader,
|
|
232
|
+
workerEnv: worker,
|
|
371
233
|
maxAttempts: 2,
|
|
372
234
|
});
|
|
373
235
|
},
|
|
374
|
-
// ── SUP: read the suspend's pending record (boundCallId/boundInputHash echoed VERBATIM — corr #2 / TOCTOU) ──
|
|
375
236
|
getCheckpoint: async (store, token, _scope) => {
|
|
376
237
|
return store.get(token);
|
|
377
238
|
},
|
|
378
|
-
// ── TEAM: the leader orchestrator via createLeaderRunner with budget-stamped workers. The leader integrates +
|
|
379
|
-
// PUSHES to a per-cell durable remote (git daemon on the CONTROL PLANE). On a DELIVERED run we bundle that
|
|
380
|
-
// integrated tree ON THE CONTROL PLANE and stash it as state.teamBundle; ensureGraderWithWorkerTree then seeds
|
|
381
|
-
// the GRADER from it directly (the worker stays the empty-base distinct env). If the integrated tree cannot be
|
|
382
|
-
// captured, runLeaderForTrap returns infraFailed (EXCLUDED, never a fabricated uniform loss). ──
|
|
383
239
|
runLeaderTask: async () => {
|
|
384
|
-
// 🔴 NETWORK ISOLATION (firm-v1/C4 drill): the leader's git daemon serves git://127.0.0.1:<port> on the CONTROL
|
|
385
|
-
// PLANE; the E2B sandboxes are network-isolated → cloning git://127.0.0.1 from INSIDE E2B hits the sandbox's own
|
|
386
|
-
// localhost ("not a git repository"). FIX: clone+bundle the integrated ref HERE on the control plane, stash the
|
|
387
|
-
// base64 bundle (+ its base hash) in state; the grader-import path (importBundleB64ToGrader via writeFile, the
|
|
388
|
-
// PROVEN control-plane↔E2B-grader transport) ships it into the grader. We never touch the E2B worker for this.
|
|
389
240
|
const captureIntegratedTreeToBundle = async (remoteUrl, targetRef) => {
|
|
390
241
|
const { execFileSync } = await import("node:child_process");
|
|
391
242
|
const { mkdtempSync, readFileSync, rmSync } = await import("node:fs");
|
|
@@ -403,25 +254,19 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
403
254
|
console.error(`[S1_DEBUG_IMPORT] cp clone --branch ${branch} failed: ${e1.stderr?.toString().slice(-200)}; retrying default`);
|
|
404
255
|
execFileSync("git", ["clone", "-q", remoteUrl, cloneDir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
405
256
|
}
|
|
406
|
-
// The integrated repo's root commit = the grader's s1-base (HEAD = the leader's merge commit, advanced past it).
|
|
407
257
|
const baseHash = execFileSync("git", ["-C", cloneDir, "rev-list", "--max-parents=0", "HEAD"]).toString().trim().split("\n").pop().trim();
|
|
408
258
|
const head = execFileSync("git", ["-C", cloneDir, "rev-parse", "HEAD"]).toString().trim();
|
|
409
259
|
if (!/^[0-9a-f]{40}$/.test(baseHash) || head === baseHash) {
|
|
410
260
|
if (process.env.S1_DEBUG_GIT)
|
|
411
261
|
console.error(`[S1_DEBUG_IMPORT] cp integrated tree not delivered: head=${head} base=${baseHash}`);
|
|
412
|
-
return false;
|
|
262
|
+
return false;
|
|
413
263
|
}
|
|
414
264
|
const bundlePath = join(tmp, "team.bundle");
|
|
415
|
-
// 🔴 git archive HEAD = the integrated WORKTREE as a tar (no .git) — the grader tar -x's plain files, never
|
|
416
|
-
// git clone (E2B grader-clone heisenbug + Kata virtiofs). delivered = head≠base from the shas computed here
|
|
417
|
-
// on the control plane (where git works). (Was: `git bundle` + grader clone — that hit both backends' git
|
|
418
|
-
// failures.) The single-revision HEAD bundle comment kept for history; we now ship a worktree tar instead.
|
|
419
|
-
// is tagged explicitly on the grader side, so delivered = HEAD≠base still resolves).
|
|
420
265
|
execFileSync("git", ["-C", cloneDir, "archive", "--format=tar", "-o", bundlePath, "HEAD"], { stdio: ["ignore", "ignore", "pipe"] });
|
|
421
|
-
const buffer = readFileSync(bundlePath);
|
|
266
|
+
const buffer = readFileSync(bundlePath);
|
|
422
267
|
if (process.env.S1_DEBUG_GIT)
|
|
423
268
|
console.error(`[S1_DEBUG_IMPORT] cp integrated head=${head} base=${baseHash} tar bytes=${buffer.length}`);
|
|
424
|
-
state.teamBundle = { buffer, head, base: baseHash };
|
|
269
|
+
state.teamBundle = { buffer, head, base: baseHash };
|
|
425
270
|
return true;
|
|
426
271
|
}
|
|
427
272
|
catch (e) {
|
|
@@ -435,39 +280,23 @@ export function buildLiveDeps(rt, trap, seed, cellId) {
|
|
|
435
280
|
};
|
|
436
281
|
return runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, captureIntegratedTreeToBundle);
|
|
437
282
|
},
|
|
438
|
-
// ── The hidden objective oracle (the measure), graded in the DISTINCT grader env ──
|
|
439
283
|
runOracle: () => runOracle(false),
|
|
440
|
-
// 🔴 runCounterfactualOracle is DELIBERATELY OMITTED (it is OPTIONAL in ProfileDeps). The honest "no counterfactual"
|
|
441
|
-
// path: buildCounterfactual returns undefined → the metric tool records UNVERIFIED-WITHHELD (NO avoided-loss
|
|
442
|
-
// credit), the documented no-fake-credit choice (README / row.ts). The previous `runCounterfactualOracle:
|
|
443
|
-
// runOracle` self-alias re-graded the IDENTICAL post-gate tree, so withoutInterventionTrulyCorrect ALWAYS
|
|
444
|
-
// equaled withInterventionTrulyCorrect → every withhold auto-credited CORRECTLY-WITHHELD (withholdPrecision a
|
|
445
|
-
// tautological 1.0); for the SUP tool-deny path the deny is a REAL durable suspend that blocked the commit, so
|
|
446
|
-
// re-grading the same blocked tree is NOT an ablation. A real ablation (re-run the SAME (trap,seed) with the
|
|
447
|
-
// gate DISABLED into a FRESH worker, grade THAT in a separate grader) is the only thing that makes
|
|
448
|
-
// INCORRECTLY-WITHHELD reachable — TODO; until it lands we honestly omit rather than manufacture credit.
|
|
449
284
|
};
|
|
450
285
|
const dispose = async () => {
|
|
451
286
|
await Promise.allSettled([state.worker?.destroy(), state.grader?.destroy()]);
|
|
452
287
|
};
|
|
453
288
|
return { deps, dispose };
|
|
454
289
|
}
|
|
455
|
-
/** The per-cell base TaskSpec every arm's leaf projects from. EXPORTED so the shape test measures the REAL spec
|
|
456
|
-
* handed to the runner (the BUDGET-MATCH anchor is spec.limits, not the harness's own RowBudget echo). */
|
|
457
290
|
export function benchBaseSpec(rt, cellId) {
|
|
458
|
-
// 🔴 core ≥5.8: maxTokens/maxCostUsd are read ONLY from `limits` — a top-level key is silently dead. No `as
|
|
459
|
-
// TaskSpec` here or in the projections below: the compiler is the guard against re-introducing dead keys.
|
|
460
291
|
return (objective) => ({
|
|
461
292
|
objective,
|
|
462
293
|
sessionId: `s1-${cellId}`,
|
|
463
294
|
limits: { maxTokens: rt.maxTokens ?? 8000, maxCostUsd: rt.maxCostUsd ?? 1.0, maxTurns: rt.maxTurns ?? 12 },
|
|
464
295
|
});
|
|
465
296
|
}
|
|
466
|
-
/** Project a `SoloImplSpec` (budget already stamped by the harness, all keys in `limits`) onto the bench base TaskSpec. */
|
|
467
297
|
export function toTaskSpec(base, impl) {
|
|
468
298
|
return { ...base(impl.objective), limits: { ...impl.limits } };
|
|
469
299
|
}
|
|
470
|
-
/** Project a `SupImplSpec` onto the bench base TaskSpec PLUS the durable wiring (checkpointStore + ask policy). */
|
|
471
300
|
export function toSupTaskSpec(base, impl, trap) {
|
|
472
301
|
const requireApproval = trap.gatedTools ?? ["Bash"];
|
|
473
302
|
const neverAuto = trap.neverAuto ?? [];
|
|
@@ -479,29 +308,7 @@ export function toSupTaskSpec(base, impl, trap) {
|
|
|
479
308
|
onQuestion: QUESTION_AWAITS_RESUME,
|
|
480
309
|
};
|
|
481
310
|
}
|
|
482
|
-
/**
|
|
483
|
-
* Run the leader (TEAM) for a trap via `createLeaderRunner`, then map its `LeaderResult` → `LeaderTaskOutcome` (the
|
|
484
|
-
* subset the harness needs for the COMPLETE TEAM cost + outcome). The leader runs its OWN integration sandbox + an
|
|
485
|
-
* objective hidden oracle (its `testCmd` over the trap's oracleSteps) and PUSHES the integrated tree to a per-cell
|
|
486
|
-
* durable remote. The harness then IMPORTS that integrated tree into state.worker (via `importIntegratedTreeToWorker`)
|
|
487
|
-
* so its `runOracle` independently re-grades the REAL integrated output in the DISTINCT grader (the trusted measure —
|
|
488
|
-
* the leader's own gate is NOT trusted as the numerator). Budget-stamped: per-worker maxCostUsd is bounded so
|
|
489
|
-
* Σworker ≤ the arm budget.
|
|
490
|
-
*
|
|
491
|
-
* 🔴 The integrated tree is the actual TEAM output. The durable remote is served over `git://127.0.0.1` by a local
|
|
492
|
-
* `git daemon` (the leader/wire.ts validator REJECTS `file://`; `git://` passes AND the Coordinator can push to
|
|
493
|
-
* it). After a delivered run the harness clones the pushed targetRef into state.worker; if that import fails (the
|
|
494
|
-
* leader never delivered, or no integrated head exists) the cell is `infraFailed:true` (EXCLUDED) — NEVER a
|
|
495
|
-
* fabricated uniform "delivered=false" loss for the whole TEAM column.
|
|
496
|
-
*
|
|
497
|
-
* 🔴 The leader's workers run on the E2B factory (each its OWN VM — isolation). A leader crash surfaces as
|
|
498
|
-
* `infraFailed:true` (EXCLUDED), never a scored loss.
|
|
499
|
-
*/
|
|
500
311
|
async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId, importIntegratedTreeToWorker) {
|
|
501
|
-
// The TEAM arm needs a durable remote to integrate into. For S1 we serve a throwaway local bare git repo over
|
|
502
|
-
// `git://127.0.0.1:<port>` via `git daemon` so (a) the leader/wire.ts validator accepts the URL (it forbids
|
|
503
|
-
// file://) and (b) the Coordinator can clone+push it. 🔴 Needs `git` (incl. `git daemon`) on the control-plane
|
|
504
|
-
// PATH (deploy req, leader/wire.ts header).
|
|
505
312
|
const { mkdtempSync, rmSync, writeFileSync, mkdirSync } = await import("node:fs");
|
|
506
313
|
const { execFileSync, spawn } = await import("node:child_process");
|
|
507
314
|
const { tmpdir } = await import("node:os");
|
|
@@ -511,9 +318,7 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
511
318
|
const repoName = "team.git";
|
|
512
319
|
const remoteDir = join(baseDir, repoName);
|
|
513
320
|
execFileSync("git", ["init", "-q", "--bare", remoteDir]);
|
|
514
|
-
// Mark the bare repo daemon-exportable (git daemon refuses to serve a repo without this unless --export-all).
|
|
515
321
|
execFileSync("git", ["--git-dir", remoteDir, "config", "daemon.receivepack", "true"]);
|
|
516
|
-
// Pick a free localhost port for the daemon (bind:0 → OS-assigned → read it back).
|
|
517
322
|
const port = await new Promise((resolve, reject) => {
|
|
518
323
|
const srv = net.createServer();
|
|
519
324
|
srv.once("error", reject);
|
|
@@ -523,8 +328,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
523
328
|
srv.close(() => (p ? resolve(p) : reject(new Error("could not pick a free port"))));
|
|
524
329
|
});
|
|
525
330
|
});
|
|
526
|
-
// Start `git daemon` serving baseDir over 127.0.0.1:port with push enabled. The URL the leader receives is
|
|
527
|
-
// git://127.0.0.1:<port>/<repoName>.
|
|
528
331
|
const daemon = spawn("git", [
|
|
529
332
|
"daemon",
|
|
530
333
|
"--reuseaddr",
|
|
@@ -535,7 +338,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
535
338
|
"--enable=receive-pack",
|
|
536
339
|
remoteDir,
|
|
537
340
|
], { stdio: "ignore" });
|
|
538
|
-
// Give the daemon a moment to bind (poll the port until it accepts, up to ~3s).
|
|
539
341
|
const waitForPort = async () => {
|
|
540
342
|
for (let i = 0; i < 30; i++) {
|
|
541
343
|
const up = await new Promise((resolve) => {
|
|
@@ -554,22 +356,13 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
554
356
|
};
|
|
555
357
|
const remoteUrl = `git://127.0.0.1:${port}/${basename(remoteDir)}`;
|
|
556
358
|
const targetRef = "refs/heads/main";
|
|
557
|
-
// Budget-stamped workers (Σ ≤ arm budget). The leader splits the arm budget across ≤2 workers for C4.
|
|
558
|
-
// 🔴 LOAD-BEARING ON THE SEQUENTIAL DRIVER (run-firm.ts: `for (const cell of cells)` is strictly sequential,
|
|
559
|
-
// one runArm at a time). loadConfig()/leaderResourceConfig() read these knobs ONLY from process.env (no
|
|
560
|
-
// parameterized override seam exists today), so env-stamping is the only lever. If run-firm's loop is ever
|
|
561
|
-
// parallelized, two cells would race on shared process.env (cross-contaminating the per-worker budget — the
|
|
562
|
-
// §3.2 fairness root); thread the config explicitly (loadConfig override args + LeaderWireConfig fields) FIRST.
|
|
563
359
|
process.env.LEADER_ENABLED = "true";
|
|
564
360
|
process.env.LEADER_WORKER_BUDGET_USD = String((rt.maxCostUsd ?? 1.0) / 2);
|
|
565
|
-
process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2";
|
|
361
|
+
process.env.LEADER_CONFLICT_ROUNDS = process.env.LEADER_CONFLICT_ROUNDS ?? "2";
|
|
566
362
|
const run = createLeaderRunner({
|
|
567
363
|
brain, models, roles, pricing, e2bApiKey: rt.e2bApiKey, workspace: W,
|
|
568
364
|
...(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) : "") } } : {}),
|
|
569
365
|
});
|
|
570
|
-
// The seed command (run in each worker + the integration sandbox): a fresh repo at base. For a hazard trap (C7)
|
|
571
|
-
// the seedFiles are written + committed INTO each worker's base (PRECIOUS sentinel + scratch) so the worker SEES
|
|
572
|
-
// them and may over-delete from its local view (search S1c fan-out hazard). Absent ⇒ an empty base.
|
|
573
366
|
const teamSeedWrite = (trap.seedFiles ?? [])
|
|
574
367
|
.map((f) => {
|
|
575
368
|
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
@@ -579,7 +372,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
579
372
|
.join("; ");
|
|
580
373
|
const teamSeedStep = trap.seedFiles && trap.seedFiles.length > 0 ? `${teamSeedWrite}; git add -A; ` : "";
|
|
581
374
|
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`;
|
|
582
|
-
// The integration testCmd = the trap's objective COMMAND oracle steps (the leader's hidden-oracle gate).
|
|
583
375
|
const testCmd = trap.oracle.oracleSteps.map((s) => s.command).join(" && ");
|
|
584
376
|
const oracleFiles = trap.oracle.hiddenTestFiles;
|
|
585
377
|
const killDaemon = () => {
|
|
@@ -587,7 +379,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
587
379
|
daemon.kill("SIGKILL");
|
|
588
380
|
}
|
|
589
381
|
catch {
|
|
590
|
-
/* already gone */
|
|
591
382
|
}
|
|
592
383
|
};
|
|
593
384
|
let res;
|
|
@@ -595,20 +386,11 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
595
386
|
if (!(await waitForPort())) {
|
|
596
387
|
return { ok: false, reports: [], infraFailed: true };
|
|
597
388
|
}
|
|
598
|
-
// 🔴 Seed the bare daemon repo's `main` with a REAL base commit + capture its sha (firm-v1/C4 dig — the deepest
|
|
599
|
-
// TEAM layer). The bare repo was EMPTY and baseSha was the literal "HEAD": the Coordinator (wire.ts) clones the
|
|
600
|
-
// durable remote then `git am`s the integrated patch and pushes `--force-with-lease=refs/heads/main:<baseSha>`.
|
|
601
|
-
// With an empty repo + a non-sha "HEAD" lease, the integrated head landed at root INTERMITTENTLY → my control-plane
|
|
602
|
-
// clone of main saw root-only (head==base) → TEAM was unmeasurable. A real base commit + the real base sha makes
|
|
603
|
-
// the Coordinator's am apply on a deterministic base and the lease exact → main = the integrated merge, always.
|
|
604
389
|
const seedDir = mkdtempSync(join(tmpdir(), "s1-team-seed-"));
|
|
605
390
|
execFileSync("git", ["clone", "-q", remoteDir, seedDir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
606
391
|
execFileSync("git", ["-C", seedDir, "config", "user.email", "s1@bench.local"]);
|
|
607
392
|
execFileSync("git", ["-C", seedDir, "config", "user.name", "s1-bench"]);
|
|
608
393
|
execFileSync("git", ["-C", seedDir, "config", "commit.gpgsign", "false"]);
|
|
609
|
-
// Hazard trap (C7): seed the durable base with the SAME files (PRECIOUS sentinel + scratch) so the merge starts
|
|
610
|
-
// from a tree CONTAINING the sentinel — a worker's over-delete then surfaces as a real deletion in the integrated
|
|
611
|
-
// tree (merge-result survival). Absent ⇒ empty base (C4 disjoint creates everything fresh).
|
|
612
394
|
for (const f of trap.seedFiles ?? []) {
|
|
613
395
|
const rel = f.path.startsWith(REPO) ? f.path.slice(REPO.length + 1) : f.path;
|
|
614
396
|
const abs = join(seedDir, rel);
|
|
@@ -629,10 +411,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
629
411
|
testCmd,
|
|
630
412
|
seedCmd,
|
|
631
413
|
oracleFiles,
|
|
632
|
-
// Fan-out plan: the explicit per-worker subtask list lives on the TrapSpec (C4 disjoint modules, C7 fan-out
|
|
633
|
-
// hazard). The leader's planner REQUIRES disjoint file ownership (a same-file plan is rejected "not disjoint").
|
|
634
|
-
// Each worker gets ONLY its local objective; the oracle checks the integrated result. Traps without subtasks
|
|
635
|
-
// stay single (the router collapses).
|
|
636
414
|
...(trap.subtasks ? { subtasks: trap.subtasks } : {}),
|
|
637
415
|
});
|
|
638
416
|
}
|
|
@@ -645,10 +423,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
645
423
|
}
|
|
646
424
|
if (process.env.S1_DEBUG_GIT)
|
|
647
425
|
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)}`);
|
|
648
|
-
// 🔴 Import the leader's INTEGRATED, pushed tree into state.worker so runOracle grades the REAL TEAM output (not
|
|
649
|
-
// an empty repo). The push leg only ran if the leader integrated+pushed successfully (res.merge.ok). If the
|
|
650
|
-
// import fails (no integrated head — leader did not deliver), mark the cell infra-failed (EXCLUDED), NEVER a
|
|
651
|
-
// fabricated uniform delivered=false loss. The daemon must stay alive for this clone, then we reap it.
|
|
652
426
|
let imported = false;
|
|
653
427
|
const merged = res.merge?.ok === true;
|
|
654
428
|
try {
|
|
@@ -662,9 +436,6 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
662
436
|
killDaemon();
|
|
663
437
|
rmSync(baseDir, { recursive: true, force: true });
|
|
664
438
|
}
|
|
665
|
-
// The leader ran but its integrated tree could not be moved into the grader path → NOT measurable. Honest
|
|
666
|
-
// infra-failed (EXCLUDED), never a fabricated loss. (A leader that legitimately withheld — held the merge — is a
|
|
667
|
-
// DIFFERENT case handled below via res.merge/repairTerminal, where !merged with a withhold terminal is expected.)
|
|
668
439
|
if (!imported && merged) {
|
|
669
440
|
return { ok: false, reports: res.reports, infraFailed: true };
|
|
670
441
|
}
|
|
@@ -672,21 +443,8 @@ async function runLeaderForTrap(rt, brain, models, roles, pricing, trap, cellId,
|
|
|
672
443
|
ok: res.ok,
|
|
673
444
|
reports: res.reports,
|
|
674
445
|
...(res.merge ? { merge: res.merge } : {}),
|
|
675
|
-
// 🔴 (review HIGH finding) a leader integration-test gate that REJECTED the merge (res.merge.ok===false,
|
|
676
|
-
// phase==="test" — the post-merge oracle/test gate caught a bad integrated tree, e.g. C7's fan-out hazard
|
|
677
|
-
// deleted the sentinel) is an HONEST WITHHOLD (the leader held a bad delivery), NOT a plain not-delivered.
|
|
678
|
-
// Without this, arms.ts withheld=false → the row is mis-booked. Surfacing withheld:true makes arms classify
|
|
679
|
-
// UNVERIFIED-WITHHELD (no counterfactual wired ⇒ NO avoided-loss credit — honest, never DELIVERED-WRONG and
|
|
680
|
-
// never a fake CORRECTLY-WITHHELD; the worker DID execute the hazard, the leader just didn't ship it).
|
|
681
446
|
...(res.merge?.ok === false && res.merge.phase === "test" ? { withheld: true } : {}),
|
|
682
|
-
// 🔴 the repair terminal (when the single-agent repair loop ran) drives the TEAM withhold classification in
|
|
683
|
-
// arms.ts (candidate_only/gave_up/conflict → withhold; oracle.unprotected → infra-failed). Passed through.
|
|
684
447
|
...(res.repairTerminal ? { repairTerminal: res.repairTerminal } : {}),
|
|
685
|
-
// A leader that integrated+pushed → the integrated tree is now in state.worker (runOracle grades it). A leader
|
|
686
|
-
// that did NOT merge (held the merge / repair non-accepting terminal) leaves state.worker empty → runOracle
|
|
687
|
-
// reports delivered=false, which is the HONEST verdict for an un-delivered TEAM run (the withhold classification
|
|
688
|
-
// in arms.ts reads merge/repairTerminal, and the absent counterfactual → UNVERIFIED-WITHHELD, no fake credit).
|
|
689
|
-
// The leader does not surface a stamped per-worker budget split here; honest "not measured" (undefined).
|
|
690
448
|
};
|
|
691
449
|
}
|
|
692
450
|
//# sourceMappingURL=live-deps.js.map
|