@sema-agent/server 1.322.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 +59 -3
- 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
package/dist/leader/leader.d.ts
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2 MVP M4 — the leader orchestrator (design/50 §3, V2-MVP-PLAN.md). Composes the proven pieces into one
|
|
3
|
+
* callable API: Planner → fanOut (M1) → diff-out (M2) → merge(b) (M3) → Coordinator push.
|
|
4
|
+
*
|
|
5
|
+
* Worker-env model (design/68 §8 F2(a)): preferred = FACTORY env (runner-owned lifecycle; durable suspend only
|
|
6
|
+
* yields a complete ownedEnv on this path) + diff-out via the worker's mandatory SELF-UPLOAD last step
|
|
7
|
+
* (`fetchDiff`, diffup.ts). Compat = the original static env the leader owns: provision up-front, pull each
|
|
8
|
+
* branch's diff OUT of the still-alive env (pullDiff), destroy every env in a `finally`.
|
|
9
|
+
* fanOut's runner just routes a sessionId to that worker's env-bound runner. This is the leaderless-leader
|
|
10
|
+
* pattern (service[19]): authority = owning the integration+verification point + disjoint file-ownership.
|
|
11
|
+
*
|
|
12
|
+
* Deps injected → mock-tested; the real-infra wiring (E2B envs + deepseek runners + git push) lives in the
|
|
13
|
+
* joint dogfood, which this generalizes.
|
|
14
|
+
*/
|
|
1
15
|
import { type RunnerLike, type WorkerReport } from "./fanout.js";
|
|
2
16
|
import { type ExecStreamLike } from "./diffout.js";
|
|
3
17
|
import { type MergeDeps, type MergeResult } from "./merge.js";
|
|
4
18
|
import { type TaskSpec, type VerifyConfig, type CheckpointToken, type ToolSpec, type RepairTerminal, type OracleTier, type RepairResult } from "@sema-agent/core";
|
|
19
|
+
/** design/74 Slice 6: drive a worker's resource-suspend auto-resume to a terminal (or bound) state. Exported
|
|
20
|
+
* for unit tests. Loops `resume(token, slice)` WHILE the result carries a `resource_limit` checkpoint gate —
|
|
21
|
+
* NOT by status (the verify wrapper may surface a suspend as failed-with-token). Exits on: a terminal result
|
|
22
|
+
* (completed/failed → no gate), an exhausted budget (core fails the resume fast → no token/gate), a
|
|
23
|
+
* human-approval gate (kind ≠ "resource_limit" — never auto-resumed), `signal.aborted`, or `maxSlices` (a
|
|
24
|
+
* belt; core's ledger fail-fast + per-task suspend-loop cap are the primary bounds). Returns the final result. */
|
|
5
25
|
export declare function autoResumeOnResource<T extends {
|
|
6
26
|
checkpointToken?: CheckpointToken;
|
|
7
27
|
checkpointGate?: {
|
|
@@ -10,35 +30,61 @@ export declare function autoResumeOnResource<T extends {
|
|
|
10
30
|
}>(initial: T, signal: {
|
|
11
31
|
readonly aborted: boolean;
|
|
12
32
|
}, resume: (token: CheckpointToken, slice: number) => Promise<T>, maxSlices?: number): Promise<T>;
|
|
33
|
+
/** A planned sub-task: a worker id, its branch, disjoint file-ownership, and the agent objective. */
|
|
13
34
|
export interface SubtaskSpec {
|
|
14
35
|
workerId: string;
|
|
15
36
|
branch: string;
|
|
16
37
|
files: string[];
|
|
17
38
|
spec: Omit<TaskSpec, "sessionId" | "signal">;
|
|
18
39
|
}
|
|
40
|
+
/** A leader-OWNED worker: its env-bound runner + the env handle to pull its diff out + lifecycle. */
|
|
19
41
|
export interface ProvisionedWorker {
|
|
20
42
|
workerId: string;
|
|
21
43
|
sessionId: string;
|
|
22
44
|
branch: string;
|
|
45
|
+
/** base commit of THIS worker's env (drives `git format-patch <baseSha>..<branch>` diff-out). */
|
|
23
46
|
baseSha: string;
|
|
47
|
+
/** runs the worker agent on this worker's env (static `executionEnv` or a factory — design/68 F2(a)). */
|
|
24
48
|
runner: RunnerLike;
|
|
49
|
+
/** Static-env mode (M2 compat): pull the worker's branch diff OUT of its (post-task, still-alive) env. */
|
|
25
50
|
diffEnv?: ExecStreamLike;
|
|
51
|
+
/** Factory-env mode (design/68 F2(a), preferred when set): fetch the diff the worker SELF-UPLOADED as its
|
|
52
|
+
* mandatory last task step (presigned MinIO object) — the env is runner-owned and already gone. */
|
|
26
53
|
fetchDiff?: () => Promise<import("./diffout.js").PullDiffResult>;
|
|
54
|
+
/** Static-env mode only: the leader owns + destroys the env. Factory envs omit this — the runner's factory
|
|
55
|
+
* lifecycle destroys them, and a SUSPENDED worker's paused env is thereby exempt from the leader's reap
|
|
56
|
+
* (design/68 row4/C4: destroying a suspended worker's env = expiring its resume token). */
|
|
27
57
|
destroy?: () => Promise<void>;
|
|
28
58
|
spec: Omit<TaskSpec, "sessionId" | "signal">;
|
|
59
|
+
/** Optional read-effect PROBE tools for the L3 verifier (verifyWorker path). The default verifierTools = the
|
|
60
|
+
* impl's tools filtered to effect:"read", which DROPS the env's write-effect `bash` → the verifier can't run
|
|
61
|
+
* python3/tests → PARTIAL. Provision a read-effect exec/probe tool here so the verifier can actually verify. */
|
|
29
62
|
verifierTools?: ToolSpec[];
|
|
30
63
|
}
|
|
31
64
|
export interface LeaderDeps {
|
|
65
|
+
/** Plan a task into N disjoint-file sub-tasks (MVP: simple/hand-authored; adaptive replan = scale). */
|
|
32
66
|
plan: (task: string) => Promise<SubtaskSpec[]>;
|
|
67
|
+
/** Provision a leader-owned worker (its env seeded with base at `branch` + an env-bound runner). */
|
|
33
68
|
provisionWorker: (sub: SubtaskSpec) => Promise<ProvisionedWorker>;
|
|
69
|
+
/** Ephemeral no-creds integration sandbox + the credentialed Coordinator push (merge(b) deps). */
|
|
34
70
|
provisionIntegrationSandbox: MergeDeps["provisionIntegrationSandbox"];
|
|
35
71
|
push: MergeDeps["push"];
|
|
72
|
+
/** Integration test command (the merge gate) + repo dir inside the sandbox. */
|
|
36
73
|
testCmd: string;
|
|
74
|
+
/** Optional truecorrect MEASURE (design/59): a thorough hidden-oracle command run IN the integration sandbox
|
|
75
|
+
* after the gate passes (NOT a gate) — offloads the measure from the control plane. Result in result.merge.measure. */
|
|
37
76
|
measureCmd?: string;
|
|
38
77
|
repoDir?: string;
|
|
78
|
+
/** Diff-out repo dir inside each WORKER env (default = repoDir). */
|
|
39
79
|
workerRepoDir?: string;
|
|
80
|
+
/** fan-out deadline + concurrency cap. */
|
|
40
81
|
timeoutMs: number;
|
|
41
82
|
maxConcurrency: number;
|
|
83
|
+
/** design/52 L3a — optional per-module sub-gate + bounded repair, run AFTER fan-out, BEFORE merge. For each
|
|
84
|
+
* completed worker: judge its module (diff) vs its sub-objective; on fail, re-run that ONE worker with the
|
|
85
|
+
* judge's feedback (bounded by maxRepairs, default 1) on its own still-alive env, then re-judge. A module that
|
|
86
|
+
* still fails is marked `failed` (merge quarantines it). Catches per-module escapes the end-integration test
|
|
87
|
+
* misses + restores cheap-team correctness by local repair (search [38] / N=6 all-or-nothing). Omit = off. */
|
|
42
88
|
moduleGate?: {
|
|
43
89
|
judge: (sub: SubtaskSpec, diff: string) => Promise<{
|
|
44
90
|
ok: boolean;
|
|
@@ -47,11 +93,34 @@ export interface LeaderDeps {
|
|
|
47
93
|
repairObjective: (sub: SubtaskSpec, reason: string) => string;
|
|
48
94
|
maxRepairs?: number;
|
|
49
95
|
};
|
|
96
|
+
/** core 1.72 native L3a (design/54 §4): when set, each worker runs via `runWithVerification` (run the module +
|
|
97
|
+
* an ADVERSARIAL DECORRELATED verifier tries to break it reading the diff/workspace + a bounded fix-loop)
|
|
98
|
+
* instead of plain fan-out. The worker runner's `models` catalog MUST carry the heterogeneous `verifierModel`
|
|
99
|
+
* (decorrelation = deployment contract). Mutually exclusive with `moduleGate` (this IS the native version). */
|
|
50
100
|
verifyWorker?: VerifyConfig;
|
|
101
|
+
/** Replan-lite (design/68 §6): bounded, DETERMINISTIC reactions — no runtime DAG surgery. When set:
|
|
102
|
+
* worker failed → redispatch ×1 on a FRESH env (clean base; a crashed worker's half-written workspace is
|
|
103
|
+
* never reused) → still failed = collapse-remainder-to-single; verify FAIL (repair already bounded inside
|
|
104
|
+
* the verify loop) → collapse; structural merge conflict → collapse + record; budgetUsd exceeded → stop
|
|
105
|
+
* fan-out, single continues. Multi-trigger arbitration priority (C6): suspended > budget > merge-conflict >
|
|
106
|
+
* verify-fail > worker-failed — only the highest-priority reaction runs. (The suspended reaction itself —
|
|
107
|
+
* cancel the others, exempt the suspended worker, surface its token — is unconditional, not gated here.) */
|
|
51
108
|
replan?: {
|
|
109
|
+
/** Fan-out budget (USD, sum of worker costs). Exceeded → stop fan-out, collapse to single (C5). */
|
|
52
110
|
budgetUsd?: number;
|
|
53
111
|
};
|
|
112
|
+
/** LEADER-REPAIRLOOP-INTEGRATION §3/§10 — the OPT-IN single-agent self-repair loop (`runRepairLoop`). When
|
|
113
|
+
* set (LEADER_REPAIR_LOOP on; the wire attaches it via `attachRepairLoopDeps`), the single-agent paths
|
|
114
|
+
* (`collapseToSingle` `:409` and the N=1 `route==="single"` path) route their solo worker through this
|
|
115
|
+
* instead of the plain fan-out map: GENERATE == one `runner.runTask`, GRADED by an ISOLATED grader (the
|
|
116
|
+
* reused integration sandbox), capped at `candidate_only` (SAFE-tier never auto-accepts). Stage-2 wires the
|
|
117
|
+
* call-sites; this is the additive dep slot. `run` returns the worker's `WorkerReport` (carrying
|
|
118
|
+
* `repairTerminal` — §10.6) so the merge push chokepoint can hold an unconfirmed candidate. Unset ⇒ the
|
|
119
|
+
* default path is byte-identical to today. */
|
|
54
120
|
repairLoop?: {
|
|
121
|
+
/** Run the bounded repair loop over a single provisioned worker; the returned report carries `repairTerminal`
|
|
122
|
+
* (and the candidate patch is surfaced on LeaderResult). The grader env / oracle steps / model ids are
|
|
123
|
+
* captured by the wire (`runRepairLoopForLeader`). */
|
|
55
124
|
run: (solo: ProvisionedWorker, sub: SubtaskSpec) => Promise<{
|
|
56
125
|
report: WorkerReport;
|
|
57
126
|
result: RepairResult;
|
|
@@ -63,6 +132,10 @@ export interface LeaderDeps {
|
|
|
63
132
|
};
|
|
64
133
|
}>;
|
|
65
134
|
};
|
|
135
|
+
/** LEADER-REPAIRLOOP-INTEGRATION §10.3/§10.4 — the merge-path push-gate extras (the wire sets them from
|
|
136
|
+
* `LEADER_MEASURE_GATES`, default OFF). Threaded straight into `MergeDeps` (`measureGates` / `strongOracleSeeded`
|
|
137
|
+
* / `measureDrivesRepair`). Unset ⇒ the merge push path is byte-identical to today (the §10.6 repairTerminal
|
|
138
|
+
* chokepoint still fires independently — it does NOT need these). */
|
|
66
139
|
mergeGates?: Pick<MergeDeps, "measureGates" | "strongOracleSeeded" | "measureDrivesRepair">;
|
|
67
140
|
logger?: {
|
|
68
141
|
warn?: (m: string, x?: Record<string, unknown>) => void;
|
|
@@ -74,23 +147,43 @@ export interface LeaderResult {
|
|
|
74
147
|
reports: WorkerReport[];
|
|
75
148
|
merge?: MergeResult;
|
|
76
149
|
cancelled: boolean;
|
|
150
|
+
/** Which route the difficulty router picked (search [43]): "single" = a 1-subtask plan, "fanout" = N. */
|
|
77
151
|
route?: "single" | "fanout";
|
|
152
|
+
/** Set when planning/provisioning failed before fan-out. */
|
|
78
153
|
error?: string;
|
|
154
|
+
/** Replan-lite (design/68 §6): which trigger won arbitration + what was done. */
|
|
79
155
|
replan?: {
|
|
80
156
|
trigger: "suspended" | "budget" | "merge-conflict" | "verify-fail" | "worker-failed";
|
|
81
157
|
redispatched?: string[];
|
|
82
158
|
collapsed?: string;
|
|
83
159
|
};
|
|
160
|
+
/** C4: suspended workers' resume tokens, surfaced to the caller (their checkpoints + paused envs are intact —
|
|
161
|
+
* the single-agent resume path owns them from here; orphan protection = the existing deadline reap). */
|
|
84
162
|
suspended?: Array<{
|
|
85
163
|
workerId: string;
|
|
86
164
|
sessionId: string;
|
|
87
165
|
}>;
|
|
166
|
+
/** design/74 Slice 6 / task#16: the diff (uncommitted work auto-committed by the belt, then diff-out) of
|
|
167
|
+
* workers that did NOT merge (failed / still-suspended). Their progress is otherwise lost — the merge only
|
|
168
|
+
* integrates COMPLETED workers — so surface it here for review/cherry-pick instead of silently dropping it
|
|
169
|
+
* (the migration-run loss: a network-failed worker's 4 commits vanished). Best-effort + non-empty only. */
|
|
88
170
|
salvaged?: Array<{
|
|
89
171
|
workerId: string;
|
|
90
172
|
sessionId: string;
|
|
91
173
|
patch: string;
|
|
92
174
|
}>;
|
|
175
|
+
/** LEADER-REPAIRLOOP-INTEGRATION §5 — the single-agent repair loop's terminal (when `LeaderDeps.repairLoop`
|
|
176
|
+
* ran on a single-agent path). Surfaced so the HTTP status map (`endpoint.ts:75`) can distinguish "abstained,
|
|
177
|
+
* awaiting a human" (`candidate_only`/`needs_human_oracle`/`conflict` → `needs_human`) from "broke"
|
|
178
|
+
* (`oracle.unprotected`/`gave_up` → `failed`). Undefined ⇒ the repair loop did not run. */
|
|
93
179
|
repairTerminal?: RepairTerminal;
|
|
180
|
+
/** LEADER-REPAIRLOOP-INTEGRATION §5/§10.7 — the held candidate when the repair loop resolved to a
|
|
181
|
+
* non-auto-accepting terminal (`candidate_only` etc.). `patch` is the worker-authored diff, DELIMITED as
|
|
182
|
+
* untrusted at the wire surface (`delimitUntrusted("CANDIDATE PATCH (untrusted worker code)", …)` — §10.7) so
|
|
183
|
+
* it can safely reach the HTTP body + a durable-approval row a human reads; `reason` is sourced ONLY from the
|
|
184
|
+
* core-sanitized `RepairResult.verification.findings[0]`, never the raw oracle trace. The push is HELD — a
|
|
185
|
+
* human `/decide` accept fires it, reject discards (an unattended `candidate_only` is never a silent push and
|
|
186
|
+
* never a silent drop — §5 invariant). */
|
|
94
187
|
candidatePatch?: {
|
|
95
188
|
patch: string;
|
|
96
189
|
tier: OracleTier;
|
|
@@ -98,5 +191,9 @@ export interface LeaderResult {
|
|
|
98
191
|
gradedHash?: string;
|
|
99
192
|
};
|
|
100
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Run a task to an integrated, pushed result. Never throws — failures (plan, provision, fan-out, merge) are
|
|
196
|
+
* captured in LeaderResult. ALWAYS destroys every provisioned worker env (leader owns the lifecycle).
|
|
197
|
+
*/
|
|
101
198
|
export declare function runLeaderTask(task: string, durableBaseSha: string, deps: LeaderDeps): Promise<LeaderResult>;
|
|
102
199
|
//# sourceMappingURL=leader.d.ts.map
|
package/dist/leader/leader.js
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* v2 MVP M4 — the leader orchestrator (design/50 §3, V2-MVP-PLAN.md). Composes the proven pieces into one
|
|
3
|
+
* callable API: Planner → fanOut (M1) → diff-out (M2) → merge(b) (M3) → Coordinator push.
|
|
4
|
+
*
|
|
5
|
+
* Worker-env model (design/68 §8 F2(a)): preferred = FACTORY env (runner-owned lifecycle; durable suspend only
|
|
6
|
+
* yields a complete ownedEnv on this path) + diff-out via the worker's mandatory SELF-UPLOAD last step
|
|
7
|
+
* (`fetchDiff`, diffup.ts). Compat = the original static env the leader owns: provision up-front, pull each
|
|
8
|
+
* branch's diff OUT of the still-alive env (pullDiff), destroy every env in a `finally`.
|
|
9
|
+
* fanOut's runner just routes a sessionId to that worker's env-bound runner. This is the leaderless-leader
|
|
10
|
+
* pattern (service[19]): authority = owning the integration+verification point + disjoint file-ownership.
|
|
11
|
+
*
|
|
12
|
+
* Deps injected → mock-tested; the real-infra wiring (E2B envs + deepseek runners + git push) lives in the
|
|
13
|
+
* joint dogfood, which this generalizes.
|
|
14
|
+
*/
|
|
1
15
|
import { fanOut } from "./fanout.js";
|
|
2
16
|
import { pullDiff } from "./diffout.js";
|
|
3
17
|
import { mergeBranches } from "./merge.js";
|
|
4
18
|
import { Runner, runWithVerification, resumeWithVerification, delimitUntrusted } from "@sema-agent/core";
|
|
19
|
+
/** design/74 Slice 6: a belt-and-suspenders bound on the leader's resource auto-resume loop. The PRIMARY bound
|
|
20
|
+
* is the resource ledger (core fails an exhausted resume fast) + core's per-task suspend-loop cap; this only
|
|
21
|
+
* guards against an unforeseen non-progressing loop. Generous so a legitimate many-slice budget never hits it. */
|
|
5
22
|
const MAX_RESUME_SLICES = 200;
|
|
23
|
+
/** design/74 Slice 6: drive a worker's resource-suspend auto-resume to a terminal (or bound) state. Exported
|
|
24
|
+
* for unit tests. Loops `resume(token, slice)` WHILE the result carries a `resource_limit` checkpoint gate —
|
|
25
|
+
* NOT by status (the verify wrapper may surface a suspend as failed-with-token). Exits on: a terminal result
|
|
26
|
+
* (completed/failed → no gate), an exhausted budget (core fails the resume fast → no token/gate), a
|
|
27
|
+
* human-approval gate (kind ≠ "resource_limit" — never auto-resumed), `signal.aborted`, or `maxSlices` (a
|
|
28
|
+
* belt; core's ledger fail-fast + per-task suspend-loop cap are the primary bounds). Returns the final result. */
|
|
29
|
+
// Generic over the result type so BOTH leader worker paths reuse it: the verify path (VerificationResult via
|
|
30
|
+
// runWithVerification/resumeWithVerification) AND the non-verify path (plain TaskResult via runTaskStream/
|
|
31
|
+
// runner.resume). The loop only reads `checkpointToken` / `checkpointGate`, both on TaskResult.
|
|
6
32
|
export async function autoResumeOnResource(initial, signal, resume, maxSlices = MAX_RESUME_SLICES) {
|
|
7
33
|
let vr = initial;
|
|
8
34
|
for (let slice = 0; vr.checkpointToken !== undefined && vr.checkpointGate?.kind === "resource_limit" && !signal.aborted && slice < maxSlices; slice++) {
|
|
@@ -10,6 +36,10 @@ export async function autoResumeOnResource(initial, signal, resume, maxSlices =
|
|
|
10
36
|
}
|
|
11
37
|
return vr;
|
|
12
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Run a task to an integrated, pushed result. Never throws — failures (plan, provision, fan-out, merge) are
|
|
41
|
+
* captured in LeaderResult. ALWAYS destroys every provisioned worker env (leader owns the lifecycle).
|
|
42
|
+
*/
|
|
13
43
|
export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
14
44
|
let subs;
|
|
15
45
|
try {
|
|
@@ -20,10 +50,12 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
20
50
|
}
|
|
21
51
|
if (subs.length === 0)
|
|
22
52
|
return { ok: false, reports: [], cancelled: false, error: "planner produced no sub-tasks" };
|
|
53
|
+
// difficulty router (search [43]): a 1-subtask plan IS the single route — run through the same N=1 pipeline.
|
|
23
54
|
const route = subs.length === 1 ? "single" : "fanout";
|
|
24
55
|
const workers = [];
|
|
25
|
-
let finalReports = [];
|
|
56
|
+
let finalReports = []; // visible to `finally` — drives the suspended-worker destroy exemption
|
|
26
57
|
try {
|
|
58
|
+
// Provision every worker env up-front (leader-owned; each outlives its task for diff-out).
|
|
27
59
|
for (const sub of subs) {
|
|
28
60
|
try {
|
|
29
61
|
workers.push(await deps.provisionWorker(sub));
|
|
@@ -34,15 +66,22 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
34
66
|
}
|
|
35
67
|
const byId = new Map(workers.map((w) => [w.workerId, w]));
|
|
36
68
|
const bySession = new Map(workers.map((w) => [w.sessionId, w]));
|
|
69
|
+
// fan-out: route each sessionId to its own env-bound runner (M1).
|
|
37
70
|
const runner = {
|
|
38
71
|
runTaskStream: (spec) => bySession.get(spec.sessionId).runner.runTaskStream(spec),
|
|
39
72
|
};
|
|
40
73
|
const toSubtask = (w) => ({
|
|
41
74
|
workerId: w.workerId, sessionId: w.sessionId, branch: w.branch, baseSha: w.baseSha, spec: w.spec,
|
|
42
75
|
});
|
|
76
|
+
// cancelOnSuspend = the unconditional C4 reaction: a suspended settle preempts the remaining fan-out.
|
|
43
77
|
const foBase = { runner, timeoutMs: deps.timeoutMs, maxConcurrency: deps.maxConcurrency, cancelOnSuspend: true, ...(deps.logger ? { logger: deps.logger } : {}) };
|
|
44
78
|
const runWave = async (sts) => {
|
|
45
79
|
if (!deps.verifyWorker) {
|
|
80
|
+
// design/74 Slice 6 (live-test bug): the NON-verify path ALSO needs the resource-suspend auto-resume.
|
|
81
|
+
// The auto-resume previously lived only in the verify path's runWorker, so a leader with NO verifier
|
|
82
|
+
// (e.g. the drill) ran via fanOut's plain runTaskStream — a resource-suspended worker was never resumed,
|
|
83
|
+
// just surfaced "suspended". Give this path its own runWorker: run, then auto-resume across slices
|
|
84
|
+
// (plain runner.resume, no verify), then map + WARN-log any non-completed worker (no silent failures).
|
|
46
85
|
return fanOut(sts, {
|
|
47
86
|
...foBase,
|
|
48
87
|
runWorker: async (st, signal) => {
|
|
@@ -58,12 +97,17 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
58
97
|
deps.logger?.warn?.("worker_failed", {
|
|
59
98
|
workerId: w.workerId, status: r.status, turns: r.stats?.turns ?? 0,
|
|
60
99
|
...(r.errorCode ? { errorCode: r.errorCode } : {}),
|
|
100
|
+
// A `blocked` worker carries its reason in `blockedReason`, NOT `errorMessage` — surface it too,
|
|
101
|
+
// else a report_blocked is a silent "worker blocked" with no WHY (clay no-silent-failures).
|
|
61
102
|
...(r.errorMessage ? { error: r.errorMessage.slice(0, 200) } : {}),
|
|
62
103
|
...(r.blockedReason ? { blockedReason: r.blockedReason.slice(0, 200) } : {}),
|
|
63
104
|
});
|
|
64
105
|
}
|
|
65
106
|
return {
|
|
66
107
|
...base,
|
|
108
|
+
// Map the TaskResult status directly (like fanOut's own mapStatus) — a `suspended` result that the
|
|
109
|
+
// auto-resume left unresumed (a non-resource gate, e.g. human-approval) stays `suspended` so the
|
|
110
|
+
// leader's C4 surface/cancel reaction still fires; only completed/timeout pass through, else failed.
|
|
67
111
|
status: r.status === "completed" ? "completed" : r.status === "suspended" ? "suspended" : r.status === "timeout" ? "timeout" : "failed",
|
|
68
112
|
stats: r.stats,
|
|
69
113
|
...(r.status === "completed" ? {} : { error: r.errorMessage ?? r.blockedReason ?? `worker ${r.status}` }),
|
|
@@ -73,6 +117,13 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
73
117
|
},
|
|
74
118
|
});
|
|
75
119
|
}
|
|
120
|
+
// design/54 §4 L3a (core 1.72 NATIVE): each worker = runWithVerification — run the module, then an
|
|
121
|
+
// ADVERSARIAL DECORRELATED verifier (a different model) tries to BREAK it (reads diff/workspace, runs
|
|
122
|
+
// probes), with a bounded fix-loop = native per-module sub-gate + repair. Replaces the hand-rolled
|
|
123
|
+
// moduleGate. verdict FAIL after maxRounds → status:"failed" (merge quarantines). Run cost incl verify+fix.
|
|
124
|
+
// Routed THROUGH fanOut (not an unbounded Promise.all — council): reuses the semaphore (maxConcurrency), the
|
|
125
|
+
// overall timeout→cancelAll, and the shared abort signal — passed into the spec so a hung/cancelled verify
|
|
126
|
+
// actually aborts (so the overall-timeout's `await work` can unblock).
|
|
76
127
|
const verify = deps.verifyWorker;
|
|
77
128
|
return fanOut(sts, {
|
|
78
129
|
...foBase,
|
|
@@ -81,14 +132,27 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
81
132
|
const base = { workerId: w.workerId, sessionId: w.sessionId, branch: w.branch, baseSha: w.baseSha };
|
|
82
133
|
const cfg = w.verifierTools ? { ...verify, verifierTools: w.verifierTools } : verify;
|
|
83
134
|
let vr = await runWithVerification(w.runner, { ...w.spec, sessionId: w.sessionId, signal }, cfg);
|
|
135
|
+
// design/74 Slice 6: auto-resume a RESOURCE-suspended worker (a per-slice budget/turn/walltime overrun)
|
|
136
|
+
// until terminal — the leader spends the worker's TOTAL budget across slices instead of failing at the
|
|
137
|
+
// first slice. Loop + exit conditions live in `autoResumeOnResource` (unit-tested).
|
|
84
138
|
vr = await autoResumeOnResource(vr, signal, async (token, slice) => {
|
|
85
139
|
deps.logger?.info?.("worker_resource_resume", { workerId: w.workerId, slice });
|
|
86
140
|
return resumeWithVerification(w.runner, token, { gate: "resource_limit", decision: "continue" }, { ...w.spec, sessionId: w.sessionId, signal }, w.spec.objective ?? "", cfg);
|
|
87
141
|
});
|
|
88
142
|
deps.logger?.info?.("verify_outcome", { workerId: w.workerId, status: vr.status, verdict: vr.verification.verdict, rounds: vr.verification.rounds, finding: (vr.verification.findings[0] ?? "").slice(0, 220) });
|
|
89
143
|
const pass = vr.status === "completed" && vr.verification.verdict === "PASS";
|
|
144
|
+
// round-3 review BLOCKER: a DURABLE suspend — resource OR human-approval — comes back from
|
|
145
|
+
// runWithVerification as failed-WITH-token (core mapNestedSuspend), so gating `stillSuspended` on
|
|
146
|
+
// `resource_limit` ONLY mis-routed a human-approval suspend to `failed` → the C4 surface/cancel
|
|
147
|
+
// reaction never fired and its paused env could be reaped. Any worker still carrying a checkpoint
|
|
148
|
+
// token is suspended (resumable); a genuine failure has no token. The resource auto-resume already
|
|
149
|
+
// ran above, so a still-tokened resource worker is one the leader couldn't fully resume (deadline).
|
|
90
150
|
const stillSuspended = vr.checkpointToken !== undefined;
|
|
91
151
|
const reportStatus = pass ? "completed" : stillSuspended ? "suspended" : "failed";
|
|
152
|
+
// No-silent-failures (clay 2026-06-15): WARN on any non-completed REPORT status — incl. a verify-FAIL
|
|
153
|
+
// on an impl that COMPLETED (vr.status "completed" but reportStatus "failed"), which the old
|
|
154
|
+
// `vr.status !== completed` guard missed. Carry the impl's reason: errorCode, errorMessage, AND
|
|
155
|
+
// blockedReason (a report_blocked worker's reason lives there, not in errorMessage), plus the verdict.
|
|
92
156
|
if (reportStatus !== "completed") {
|
|
93
157
|
deps.logger?.warn?.("worker_failed", {
|
|
94
158
|
workerId: w.workerId, status: reportStatus, turns: vr.stats?.turns ?? 0, verdict: vr.verification.verdict,
|
|
@@ -100,6 +164,8 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
100
164
|
return {
|
|
101
165
|
...base, status: reportStatus, stats: vr.stats,
|
|
102
166
|
moduleJudge: vr.verification.verdict === "PASS" ? "pass" : "fail", repairs: Math.max(0, vr.verification.rounds - 1),
|
|
167
|
+
// A verify FAIL/PARTIAL (the impl completed but the verifier rejected it) reports the verdict;
|
|
168
|
+
// an `unverified` (the impl didn't complete — suspend/block/error) reports the impl's own reason.
|
|
103
169
|
...(pass
|
|
104
170
|
? {}
|
|
105
171
|
: {
|
|
@@ -113,8 +179,18 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
113
179
|
},
|
|
114
180
|
});
|
|
115
181
|
};
|
|
182
|
+
// LEADER-REPAIRLOOP-INTEGRATION §10.6 — the single-agent repair loop's terminal + held candidate, lifted onto
|
|
183
|
+
// every terminal LeaderResult. Set ONLY when `deps.repairLoop` ran on a single-agent path (LEADER_REPAIR_LOOP
|
|
184
|
+
// on); undefined otherwise → the result is byte-identical to today. The `repairTerminal` ALSO rides on the
|
|
185
|
+
// solo worker's report (so the merge push chokepoint, merge.ts, holds an unconfirmed candidate by construction).
|
|
116
186
|
let repairTerminal;
|
|
117
187
|
let candidatePatch;
|
|
188
|
+
// Route a SINGLE provisioned worker through the opt-in `runRepairLoop` (when `deps.repairLoop` is set) instead
|
|
189
|
+
// of the plain fan-out map: GENERATE == one runner.runTask, GRADED by the isolated grader, capped at
|
|
190
|
+
// `candidate_only`. Attaches `repairTerminal` to the report (the chokepoint reads it) + lifts the held
|
|
191
|
+
// candidate. Falls back to `runWave([toSubtask(solo)])` (today's path) when the repair loop is not attached
|
|
192
|
+
// OR the per-worker resolve throws (never break the leader). Returns the same shape as `runWave` so the
|
|
193
|
+
// call-sites are a drop-in. §10.6: this covers BOTH single-agent paths (collapse + N=1) through one helper.
|
|
118
194
|
const runSolo = async (solo, sub) => {
|
|
119
195
|
if (!deps.repairLoop)
|
|
120
196
|
return runWave([toSubtask(solo)]);
|
|
@@ -127,10 +203,14 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
127
203
|
return { reports: [rr.report], cancelled: false };
|
|
128
204
|
}
|
|
129
205
|
catch (e) {
|
|
206
|
+
// The repair wire already maps a thrown engine error to a failed report; a throw HERE is a wire/resolve
|
|
207
|
+
// failure — degrade to the plain wave so the solo still runs (no silent break; warn the WHY).
|
|
130
208
|
deps.logger?.warn?.("repair_loop_dispatch_failed", { workerId: solo.workerId, err: e instanceof Error ? e.message : String(e) });
|
|
131
209
|
return runWave([toSubtask(solo)]);
|
|
132
210
|
}
|
|
133
211
|
};
|
|
212
|
+
// N=1 (route==="single"): the lone worker IS the single-agent path → route it through `runSolo`. With
|
|
213
|
+
// `deps.repairLoop` unset, `runSolo` delegates straight to `runWave` → byte-identical to today's `runWave(...)`.
|
|
134
214
|
const fo1 = route === "single" && workers.length === 1
|
|
135
215
|
? await runSolo(workers[0], subs[0])
|
|
136
216
|
: await runWave(workers.map(toSubtask));
|
|
@@ -138,11 +218,17 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
138
218
|
let cancelled = fo1.cancelled;
|
|
139
219
|
finalReports = reports;
|
|
140
220
|
const workerRepoDir = deps.workerRepoDir ?? deps.repoDir;
|
|
221
|
+
// One diff source per worker: self-uploaded (factory env, F2(a)) preferred; else pull from the static env.
|
|
141
222
|
const workerDiff = (w) => w.fetchDiff
|
|
142
223
|
? w.fetchDiff()
|
|
143
224
|
: w.diffEnv
|
|
144
225
|
? pullDiff(w.diffEnv, w.baseSha, { ref: w.branch, ...(workerRepoDir ? { cwd: workerRepoDir } : {}) })
|
|
145
226
|
: Promise.resolve({ ok: false, error: `worker ${w.workerId} has neither fetchDiff nor diffEnv` });
|
|
227
|
+
// design/74 Slice 6 (task#16, round-3 review BLOCKER): salvage the diff (belt auto-commit + diff-out) of
|
|
228
|
+
// workers that did NOT merge (failed / still-suspended) so their progress isn't silently dropped. Must run
|
|
229
|
+
// on EVERY terminal LeaderResult path — the main merge AND the early returns (surfaceSuspended, collapse) —
|
|
230
|
+
// not just the merge, else a suspended-preempted or collapsed run loses the non-completed workers' work.
|
|
231
|
+
// Best-effort: a fetch failure or an empty/paused-env diff is skipped; it NEVER blocks the result.
|
|
146
232
|
const salvageNonCompleted = async (rs) => {
|
|
147
233
|
const out = [];
|
|
148
234
|
await Promise.all(rs
|
|
@@ -157,10 +243,19 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
157
243
|
out.push({ workerId: r.workerId, sessionId: r.sessionId, patch: d.patch });
|
|
158
244
|
}
|
|
159
245
|
catch {
|
|
246
|
+
/* best-effort — a salvage fetch must not break the leader result */
|
|
160
247
|
}
|
|
161
248
|
}));
|
|
162
249
|
return out;
|
|
163
250
|
};
|
|
251
|
+
// design/52 L3a — per-module sub-gate + bounded repair (between fan-out and merge). Judge each completed
|
|
252
|
+
// worker's module diff vs its sub-objective; on fail, re-run that ONE worker with feedback (bounded), then
|
|
253
|
+
// re-judge. Still-failing modules → status:"failed" so merge quarantines them. Reaps per-module escapes the
|
|
254
|
+
// end-integration test can't see + restores cheap-team correctness via localized repair (search [38]).
|
|
255
|
+
// design/158 A13: lifted from an inline `if (deps.moduleGate) { await Promise.all(...) }` block into a named
|
|
256
|
+
// stage function (same closure scope/capture/call-site as before — behavior identical), alongside the other
|
|
257
|
+
// already-named internal stages of this function (runWave/runSolo/salvageNonCompleted/surfaceSuspended/
|
|
258
|
+
// collapseToSingle below).
|
|
164
259
|
const runModuleGate = async () => {
|
|
165
260
|
if (!deps.moduleGate)
|
|
166
261
|
return;
|
|
@@ -172,7 +267,7 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
172
267
|
for (let attempt = 0; attempt <= maxR; attempt++) {
|
|
173
268
|
const d = await workerDiff(w);
|
|
174
269
|
if (!d.ok)
|
|
175
|
-
return;
|
|
270
|
+
return; // diff-out problem → leave it for merge to quarantine
|
|
176
271
|
const verdict = await deps.moduleGate.judge(sub, d.patch);
|
|
177
272
|
r.moduleJudge = verdict.ok ? "pass" : "fail";
|
|
178
273
|
r.repairs = attempt;
|
|
@@ -187,7 +282,7 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
187
282
|
try {
|
|
188
283
|
const rr = await w.runner.runTaskStream({ ...sub.spec, objective: deps.moduleGate.repairObjective(sub, verdict.reason ?? ""), sessionId: `${w.sessionId}-r${attempt + 1}` }).result();
|
|
189
284
|
if (r.stats && rr?.stats)
|
|
190
|
-
r.stats = { ...r.stats, tokens: (r.stats.tokens ?? 0) + (rr.stats.tokens ?? 0), costMicroUsd: (r.stats.costMicroUsd ?? 0) + (rr.stats.costMicroUsd ?? 0) };
|
|
285
|
+
r.stats = { ...r.stats, tokens: (r.stats.tokens ?? 0) + (rr.stats.tokens ?? 0), costMicroUsd: (r.stats.costMicroUsd ?? 0) + (rr.stats.costMicroUsd ?? 0) }; // fold repair cost into the worker's report
|
|
191
286
|
}
|
|
192
287
|
catch (e) {
|
|
193
288
|
r.status = "failed";
|
|
@@ -198,6 +293,7 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
198
293
|
}));
|
|
199
294
|
};
|
|
200
295
|
await runModuleGate();
|
|
296
|
+
// merge(b) deps: diff-out per worker (self-upload or static pull), integrate, Coordinator push.
|
|
201
297
|
const mergeDeps = {
|
|
202
298
|
pullWorkerDiff: async (r) => workerDiff(byId.get(r.workerId)),
|
|
203
299
|
provisionIntegrationSandbox: deps.provisionIntegrationSandbox,
|
|
@@ -205,12 +301,23 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
205
301
|
testCmd: deps.testCmd,
|
|
206
302
|
...(deps.measureCmd ? { measureCmd: deps.measureCmd } : {}),
|
|
207
303
|
...(deps.repoDir ? { repoDir: deps.repoDir } : {}),
|
|
304
|
+
// §10.3/§10.4 — the push-gate extras (OFF by default; set by the wire from LEADER_MEASURE_GATES).
|
|
208
305
|
...(deps.mergeGates?.measureGates ? { measureGates: true } : {}),
|
|
209
306
|
...(deps.mergeGates?.strongOracleSeeded ? { strongOracleSeeded: true } : {}),
|
|
210
307
|
...(deps.mergeGates?.measureDrivesRepair ? { measureDrivesRepair: deps.mergeGates.measureDrivesRepair } : {}),
|
|
211
308
|
...(deps.logger ? { logger: deps.logger } : {}),
|
|
212
309
|
};
|
|
310
|
+
// ── replan-lite (design/68 §6): deterministic reaction table, arbitrated in C6 priority order ──
|
|
311
|
+
// Spec priority: suspended > budget > merge-conflict > verify-fail > worker-failed; only the highest-
|
|
312
|
+
// priority reaction runs, and the check order below IS the arbitration (each returns; later checks never
|
|
313
|
+
// see its trigger). DETECTION order differs for merge-conflict: it is only observable AFTER mergeBranches
|
|
314
|
+
// runs, i.e. after the verify/failed reactions — which is spec-equivalent, because all three reactions are
|
|
315
|
+
// the same collapse-to-single (the ordering only affects the recorded `trigger` label, and a verify/failed
|
|
316
|
+
// collapse removes the conflicting diff before a merge could ever surface its conflict).
|
|
213
317
|
let redispatched;
|
|
318
|
+
// C4 (unconditional): a suspended worker preempted the wave (fan-out cancelOnSuspend already cancelled the
|
|
319
|
+
// rest). NO merge, NO redispatch — surface failed + the resume token; its checkpoint + paused env are intact
|
|
320
|
+
// (the finally below exempts it from the static-env destroy; factory envs are exempt by construction).
|
|
214
321
|
const surfaceSuspended = async (rs, wave) => {
|
|
215
322
|
const sus = wave.filter((r) => r.status === "suspended");
|
|
216
323
|
if (sus.length === 0)
|
|
@@ -225,9 +332,16 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
225
332
|
...(salvaged.length > 0 ? { salvaged } : {}),
|
|
226
333
|
};
|
|
227
334
|
};
|
|
335
|
+
// Collapse-to-single (at most once): one fresh worker redoes the whole task on a clean branch. The discarded
|
|
336
|
+
// workers' envs die via the normal lifecycle (factory finish / the static finally) — E1. The full env-layer
|
|
337
|
+
// "adopt N half-done workspaces" seam (design/68 §8) stays future; INSTEAD (search 2026-06-16) we REUSE the
|
|
338
|
+
// fan-out work the lightweight, zero-new-seam way — hand the collapse-solo the diffs the parallel workers
|
|
339
|
+
// already produced as reference so it adapts their correct output (copy the non-overlapping modules, resolve
|
|
340
|
+
// only the overlap) rather than re-deriving the whole task blind.
|
|
228
341
|
const collapseToSingle = async (trigger, reason, priorMerge) => {
|
|
229
342
|
deps.logger?.warn?.("replan_collapse_to_single", { trigger, reason: reason.slice(0, 300) });
|
|
230
343
|
const replan = { trigger, collapsed: reason.slice(0, 300), ...(redispatched ? { redispatched } : {}) };
|
|
344
|
+
// Best-effort gather of the fan-out workers' diffs (same source as salvage); an empty/failed diff is omitted.
|
|
231
345
|
const priorDiffs = [];
|
|
232
346
|
await Promise.all(reports.map(async (r) => {
|
|
233
347
|
const w = byId.get(r.workerId);
|
|
@@ -239,6 +353,7 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
239
353
|
priorDiffs.push({ workerId: r.workerId, status: r.status, patch: d.patch });
|
|
240
354
|
}
|
|
241
355
|
catch {
|
|
356
|
+
/* best-effort — a salvage fetch must not break the collapse path */
|
|
242
357
|
}
|
|
243
358
|
}));
|
|
244
359
|
if (priorDiffs.length > 0)
|
|
@@ -250,8 +365,11 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
250
365
|
``,
|
|
251
366
|
`--- PRIOR PARALLEL WORK — REUSE IT, do not re-derive from scratch ---`,
|
|
252
367
|
`${priorDiffs.length} worker(s) attempted this task in parallel; their changes could NOT be integrated cleanly (${reason.slice(0, 150)}). Each worker's diff over the base is below. COPY the correct, non-overlapping parts verbatim and produce ONE coherent change for the WHOLE task, resolving only the overlaps. Treat these as a strong starting point — fix anything wrong, but do not throw the work away.`,
|
|
368
|
+
// BL-30/BL-32 — each prior worker's diff is untrusted worker-authored code; delimit it so an injected
|
|
369
|
+
// instruction in a diff comment can't steer the collapse-solo agent (design/53 trifecta).
|
|
253
370
|
...priorDiffs.map((d) => delimitUntrusted(`PRIOR WORKER '${d.workerId}' (${d.status}) DIFF (untrusted)`, d.patch.slice(0, 8000))),
|
|
254
371
|
].join("\n");
|
|
372
|
+
// The synthetic collapse-solo sub-task (kept as a value so the §10.6 repair-loop dispatch can pass it).
|
|
255
373
|
const soloSub = { workerId: "collapse-solo", branch: "worker/collapse-solo", files: ["."], spec: { objective: soloObjective } };
|
|
256
374
|
let solo;
|
|
257
375
|
try {
|
|
@@ -264,12 +382,18 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
264
382
|
workers.push(solo);
|
|
265
383
|
byId.set(solo.workerId, solo);
|
|
266
384
|
bySession.set(solo.sessionId, solo);
|
|
385
|
+
// §10.6: collapse-to-single IS a single-agent path → route through `runSolo` (the opt-in repair loop when
|
|
386
|
+
// `deps.repairLoop` is set; the plain wave otherwise). `runSolo` sets the outer `repairTerminal`/
|
|
387
|
+
// `candidatePatch`, which are lifted onto this return so the chokepoint-held candidate reaches the caller.
|
|
267
388
|
const fo = await runSolo(solo, soloSub);
|
|
268
389
|
finalReports = [...reports, ...fo.reports];
|
|
269
390
|
const sus = await surfaceSuspended(finalReports, fo.reports);
|
|
270
391
|
if (sus)
|
|
271
392
|
return { ...sus, replan: { ...replan, trigger: "suspended" }, ...(repairTerminal ? { repairTerminal } : {}), ...(candidatePatch ? { candidatePatch } : {}) };
|
|
272
393
|
const mRaw = await mergeBranches(fo.reports, durableBaseSha, mergeDeps);
|
|
394
|
+
// wq64gmm5e: carry the FAILED prior merge's resolver spend across the collapse so captureTeamC1 sees the
|
|
395
|
+
// tokens it already burned (a --3way conflict that triggered collapse may have run a conflictResolver). Fold
|
|
396
|
+
// it into the collapse-merge's conflictResolverCostUsd; default path (no prior cost) is byte-identical.
|
|
273
397
|
const priorCost = priorMerge?.conflictResolverCostUsd ?? 0;
|
|
274
398
|
const m = priorCost > 0 ? { ...mRaw, conflictResolverCostUsd: (mRaw.conflictResolverCostUsd ?? 0) + priorCost } : mRaw;
|
|
275
399
|
const salvaged = await salvageNonCompleted(finalReports);
|
|
@@ -287,16 +411,22 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
287
411
|
const sus1 = await surfaceSuspended(reports, reports);
|
|
288
412
|
if (sus1)
|
|
289
413
|
return sus1;
|
|
414
|
+
// C5 budget: fan-out overspent → stop fanning, single continues (no expire of anything — C7 falls out of
|
|
415
|
+
// the suspended check above winning first).
|
|
290
416
|
if (deps.replan?.budgetUsd !== undefined) {
|
|
291
417
|
const spent = reports.reduce((s, r) => s + (r.stats?.costMicroUsd ?? 0) / 1e6, 0);
|
|
292
418
|
if (spent > deps.replan.budgetUsd) {
|
|
293
419
|
return collapseToSingle("budget", `fan-out spent $${spent.toFixed(4)} > budget $${deps.replan.budgetUsd}`);
|
|
294
420
|
}
|
|
295
421
|
}
|
|
422
|
+
// C2 verify FAIL: the bounded repair was already spent INSIDE the verify loop (runWithVerification rounds /
|
|
423
|
+
// moduleGate repairs) — a worker still failing its module gate collapses, it is not redispatched.
|
|
296
424
|
if (deps.replan && reports.some((r) => r.moduleJudge === "fail")) {
|
|
297
425
|
const failed = reports.filter((r) => r.moduleJudge === "fail").map((r) => r.workerId);
|
|
298
426
|
return collapseToSingle("verify-fail", `module verification failed after bounded repair: ${failed.join(", ")}`);
|
|
299
427
|
}
|
|
428
|
+
// C1 worker failed: redispatch ×1, same spec, FRESH env + clean base (provisionWorker provisions anew; the
|
|
429
|
+
// crashed worker's half-written workspace is never reused) → still failed = collapse-remainder-to-single.
|
|
300
430
|
if (deps.replan) {
|
|
301
431
|
const failedIds = reports.filter((r) => r.status === "failed").map((r) => r.workerId);
|
|
302
432
|
if (failedIds.length > 0) {
|
|
@@ -307,7 +437,7 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
307
437
|
for (const id of failedIds) {
|
|
308
438
|
const w = await deps.provisionWorker(subById.get(id));
|
|
309
439
|
fresh.push(w);
|
|
310
|
-
workers.push(w);
|
|
440
|
+
workers.push(w); // register IMMEDIATELY — a later provision throw must not orphan this env (council)
|
|
311
441
|
}
|
|
312
442
|
}
|
|
313
443
|
catch (e) {
|
|
@@ -331,16 +461,28 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
331
461
|
}
|
|
332
462
|
}
|
|
333
463
|
}
|
|
464
|
+
// merge(b): integrate + Coordinator push.
|
|
334
465
|
const merge = await mergeBranches(reports, durableBaseSha, mergeDeps);
|
|
466
|
+
// C3 merge conflict: merge(b)'s sequential --3way apply IS the serial replay; a --3way failure means an
|
|
467
|
+
// architecture-level conflict → collapse to single + RECORD (the design/52 data feed).
|
|
335
468
|
if (!merge.ok && merge.phase === "apply" && deps.replan) {
|
|
336
469
|
deps.logger?.warn?.("replan_merge_conflict", { reason: merge.reason, quarantine: merge.quarantine ?? [] });
|
|
337
470
|
return collapseToSingle("merge-conflict", merge.reason, merge);
|
|
338
471
|
}
|
|
472
|
+
// design/74 Slice 6 (task#16): salvage the progress of workers that did NOT merge (failed / still-
|
|
473
|
+
// suspended). The belt auto-commit + diff-out ran on env teardown, so a non-empty patch exists (in S3 for a
|
|
474
|
+
// factory worker, or pullable from a still-alive static env, before the `finally` destroys it) — surface it
|
|
475
|
+
// so the work isn't silently lost (the migration-run loss: a network-failed worker's commits vanished).
|
|
476
|
+
// Best-effort: a fetch failure or an empty/paused-env diff is skipped, and it NEVER blocks the merge result.
|
|
339
477
|
const salvaged = await salvageNonCompleted(reports);
|
|
340
478
|
return {
|
|
341
479
|
ok: merge.ok, reports, merge, cancelled, route,
|
|
342
480
|
...(redispatched ? { replan: { trigger: "worker-failed", redispatched } } : {}),
|
|
343
481
|
...(salvaged.length > 0 ? { salvaged } : {}),
|
|
482
|
+
// §10.6 — lift the single-agent repair loop's terminal (set by `runSolo` on the N=1 path) + the merge
|
|
483
|
+
// chokepoint's terminal onto the result so the HTTP status map (`endpoint.ts:75`) surfaces `needs_human`.
|
|
484
|
+
// `repairTerminal` (the loop's own) takes precedence over `merge.terminal` (the chokepoint's). Both undefined
|
|
485
|
+
// on the default path → byte-identical. The held `candidatePatch` (delimited at the wire) rides alongside.
|
|
344
486
|
...(repairTerminal ?? merge.terminal ? { repairTerminal: repairTerminal ?? merge.terminal } : {}),
|
|
345
487
|
...(candidatePatch
|
|
346
488
|
? { candidatePatch }
|
|
@@ -350,6 +492,11 @@ export async function runLeaderTask(task, durableBaseSha, deps) {
|
|
|
350
492
|
};
|
|
351
493
|
}
|
|
352
494
|
finally {
|
|
495
|
+
// Static envs: the leader owns the lifecycle — destroy on EVERY path, EXCEPT a suspended worker's env
|
|
496
|
+
// (C4: destroying it kills the resume; its checkpoint + paused env belong to the single-agent resume path,
|
|
497
|
+
// orphan protection = the existing deadline reap). Factory envs carry no `destroy` (runner-owned).
|
|
498
|
+
// Keyed by sessionId, not workerId: a redispatched worker shares its predecessor's workerId — exempting by
|
|
499
|
+
// workerId would also spare the ORIGINAL failed worker's env (leak, council finding).
|
|
353
500
|
const suspendedSessions = new Set(finalReports.filter((r) => r.status === "suspended").map((r) => r.sessionId));
|
|
354
501
|
await Promise.allSettled(workers.filter((w) => w.destroy && !suspendedSessions.has(w.sessionId)).map((w) => w.destroy()));
|
|
355
502
|
}
|